分库分表

分库分表是为了应对海量数据或高并发场景的一种数据库架构优化技术,其核心思想是通过水平和垂直切分的方式,将数据分散到多个库或表中,提升系统的读写性能和扩展性。
以下是分库分表的相关概念、策略和实现细节:

分库分表的两种主要策略

  1. 水平分片(Sharding)
    1. 特点:将同一张表的数据按某种规则拆分到多个库或表中。
    2. 适用场景:单表数据量过大,查询效率降低。
    3. 实现方式
      • 按字段取模(如:user_id % N)。
      • 按范围(如:1-100万用户放入库1,100万-200万放入库2)。
      • 按哈希分布。
  2. 垂直拆分(Vertical Partitioning)
    1. 特点:按照业务模块将不同的表分布到不同的库中。
    2. 适用场景:数据库中表过多或存在跨业务查询。
    3. 实现方式
      • 不同的业务模块(如用户、订单)分配到不同的数据库。

分库分表的核心问题及解决方案

  1. 路由问题
    1. 问题:如何根据分库分表规则定位具体的库或表。
    2. 解决方案:
      • 自定义路由规则(如基于 user_id 的哈希算法)。
      • 使用中间件(如 ShardingSphere、MyCAT)来自动路由。
  2. 事务问题
    1. 问题:分布式事务在多库间的操作会非常复杂。
    2. 解决方案:
      • 两阶段提交(2PC):通过事务协调器保证分布式事务。
      • TCC 模式(Try-Confirm-Cancel):需要业务逻辑支持。
      • BASE 理论:允许弱一致性,最终达到一致性。
  3. 跨库/跨表查询问题
    1. 问题:分库分表后,涉及多个库或表的数据查询会变得复杂。
    2. 解决方案:
      • 聚合查询:通过代码逻辑在应用层进行数据整合。
      • 中间件支持:如 ShardingSphere 提供 SQL 聚合查询功能。
  4. 主键冲突问题
    1. 问题:分库分表后,各表可能会产生主键冲突。
    2. 解决方案:
      • 全局唯一 ID:使用分布式 ID 生成器(如 Snowflake 算法)。
      • 字段前缀:通过库/表编号给主键加前缀。

常见中间件解决方案

  1. ShardingSphere
      1. 特点:支持分库分表、读写分离、分布式事务。
      2. 使用方式:基于 Spring Boot 直接配置。
      3. 示例配置:
    复制代码
    spring:
      shardingsphere:
        datasource:
          names: ds0, ds1
          ds0:
            url: jdbc:mysql://localhost:3306/db0
            username: root
            password: root
          ds1:
            url: jdbc:mysql://localhost:3306/db1
            username: root
            password: root
        sharding:
          tables:
            user:
              actual-data-nodes: ds${0..1}.user_${0..1}
              table-strategy:
                inline:
                  sharding-column: user_id
                  algorithm-expression: user_${user_id % 2}
              database-strategy:
                inline:
                  sharding-column: user_id
                  algorithm-expression: ds${user_id % 2}
    复制代码

     

  2. MyCAT
    1. 特点:基于代理模式,支持分库分表和读写分离。
    2. 缺点:需要额外维护 MyCAT 服务器。
  3. Vitess
    1. 特点:由 YouTube 开发,支持 MySQL 的分库分表。
  4. TDDL
    1. 特点:阿里巴巴的分库分表框架。

分库分表的实现示例

以用户表为例,将用户数据按 user_id % 2 分到两个库,每个库中包含两张表。

数据库结构

  • 库1db1,包含表 user_0user_1
  • 库2db2,包含表 user_0user_1

自定义分库分表代码

复制代码
public class ShardingRouter {
    private static final int DATABASE_COUNT = 2; // 数据库数量
    private static final int TABLE_COUNT = 2;    // 每个库中的表数量
    /**
     * 根据 userId 获取数据库名称
     */
    public static String getDatabaseName(int userId) {
        int dbIndex = userId % DATABASE_COUNT;
        return "db" + (dbIndex + 1); // 数据库命名:db1, db2
    }
    /**
     * 根据 userId 获取表名称
     */
    public static String getTableName(int userId) {
        int tableIndex = userId % TABLE_COUNT;
        return "user_" + tableIndex; // 表命名:user_0, user_1
    }
    public static void main(String[] args) {
        int userId = 12345;
        String dbName = getDatabaseName(userId);
        String tableName = getTableName(userId);
        System.out.println("数据库:" + dbName + ",表:" + tableName);
    }
}
复制代码

 


分库分表适用场景

  • 大型电商平台:订单、用户、商品等海量数据的存储与查询。
  • 物流系统:包裹信息存储。
  • 银行业务:交易流水数据。
posted @   枯藤老樹昏鴉  阅读(227)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
点击右上角即可分享
微信分享提示