MySQL水平分表
水平分表概述
1. 什么是水平分表
graph TD
    app[应用服务器]
    shard1[分片1]
    shard2[分片2]
    shard3[分片3]
    app -->|数据路由| shard1
    app -->|数据路由| shard2
    app -->|数据路由| shard3
水平分表是将同一个表的数据按照某种规则分散到多个物理表中,每个表的结构相同。
2. 水平分表的优势
- 提高查询性能
 - 减少单表数据量
 - 提高并发能力
 - 便于维护管理
 
分片策略
1. 范围分片
-- 按ID范围分片
CREATE TABLE orders_1 (
    id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL(10,2),
    create_time DATETIME
) ENGINE=InnoDB;
CREATE TABLE orders_2 (
    id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL(10,2),
    create_time DATETIME
) ENGINE=InnoDB;
-- 分片规则:id <= 1000000 在orders_1,id > 1000000 在orders_2
2. 哈希分片
-- 按用户ID哈希分片
CREATE TABLE orders_0 (
    id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL(10,2),
    create_time DATETIME
) ENGINE=InnoDB;
CREATE TABLE orders_1 (
    id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL(10,2),
    create_time DATETIME
) ENGINE=InnoDB;
-- 分片规则:user_id % 2 决定分片
3. 时间分片
-- 按时间分片
CREATE TABLE orders_202301 (
    id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL(10,2),
    create_time DATETIME
) ENGINE=InnoDB;
CREATE TABLE orders_202302 (
    id INT PRIMARY KEY,
    user_id INT,
    amount DECIMAL(10,2),
    create_time DATETIME
) ENGINE=InnoDB;
-- 分片规则:按月份分片
实现方式
1. 应用层实现
// 分片路由
public class OrderShardingStrategy {
    public String getTableName(Long orderId) {
        return "orders_" + (orderId % 2);
    }
    public String getTableNameByUserId(Long userId) {
        return "orders_" + (userId % 2);
    }
}
// 数据访问
@Service
public class OrderService {
    @Autowired
    private OrderShardingStrategy shardingStrategy;
    public void saveOrder(Order order) {
        String tableName = shardingStrategy.getTableName(order.getId());
        // 插入对应分片表
    }
    public Order getOrder(Long orderId) {
        String tableName = shardingStrategy.getTableName(orderId);
        // 从对应分片表查询
    }
}
2. 中间件实现
# ShardingSphere配置
spring:
  shardingsphere:
    datasource:
      names: ds0
      ds0:
        type: com.zaxxer.hikari.HikariDataSource
        driver-class-name: com.mysql.cj.jdbc.Driver
        url: jdbc:mysql://localhost:3306/orders
        username: root
        password: root
    rules:
      sharding:
        tables:
          orders:
            actual-data-nodes: ds0.orders_$->{0..1}
            table-strategy:
              standard:
                sharding-column: user_id
                algorithm-name: orders_inline
        sharding-algorithms:
          orders_inline:
            type: INLINE
            props:
              algorithm-expression: orders_$->{user_id % 2}
最佳实践
1. 分片键选择
- 选择业务主键
 - 避免跨分片查询
 - 考虑数据分布
 - 便于扩展
 
2. 分片数量
- 考虑数据量
 - 考虑并发量
 - 考虑扩展性
 - 考虑维护成本
 
3. 查询优化
- 避免跨分片查询
 - 使用分片键查询
 - 合理使用索引
 - 控制查询范围
 
注意事项
- 
事务处理
- 分布式事务
 - 跨分片事务
 - 事务一致性
 - 性能影响
 
 - 
跨分片查询
- 查询性能
 - 结果合并
 - 排序分页
 - 数据一致性
 
 - 
分片扩展
- 数据迁移
 - 路由调整
 - 服务升级
 - 监控告警
 
 - 
运维管理
- 监控告警
 - 性能分析
 - 容量规划
 - 故障处理