Skip to content

MySQL 分库分表方案

TIP

当单表数据量超过千万级时,查询性能会明显下降。分库分表是解决大数据量问题的常用方案。

分表策略

垂直分表

将表的列拆分到不同表。

sql
-- 原表(大宽表)
CREATE TABLE article (
    id BIGINT PRIMARY KEY,
    title VARCHAR(200),
    content LONGTEXT,    -- 大字段,查询频率低
    author VARCHAR(50),
    created_at DATETIME
);

-- 拆分为
CREATE TABLE article_base (       -- 常用字段
    id BIGINT PRIMARY KEY,
    title VARCHAR(200),
    author VARCHAR(50),
    created_at DATETIME
);
CREATE TABLE article_content (    -- 大字段
    article_id BIGINT PRIMARY KEY,
    content LONGTEXT
);

水平分表

按某个字段的哈希值或范围划分数据。

sql
-- 按用户 ID 取模分表
order_0, order_1, order_2, order_3
-- 路由规则:order_tab = user_id % 4

分库策略

垂直分库

按业务模块拆分到不同数据库实例。

user_db        → 用户相关表
order_db       → 订单相关表
product_db     → 商品相关表

水平分库

将同一张表的数据分散到多个数据库实例。

order_db_0     → user_id 0-1000万
order_db_1     → user_id 1000万-2000万
order_db_2     → user_id 2000万-3000万

常见的中间件

中间件优点缺点
ShardingSphere-JDBC应用级,性能好代码侵入
MyCAT透明代理功能有限
ShardingSphere-Proxy透明代理多一层网络开销

ShardingSphere 配置示例

yaml
spring:
  shardingsphere:
    datasource:
      names: ds0,ds1
      ds0:
        url: jdbc:mysql://localhost:3306/db0
      ds1:
        url: jdbc:mysql://localhost:3306/db1
    rules:
      sharding:
        tables:
          order:
            actual-data-nodes: ds${0..1}.order_${0..3}
            table-strategy:
              standard:
                sharding-column: user_id
                sharding-algorithm-name: order-inline
        sharding-algorithms:
          order-inline:
            type: INLINE
            props:
              algorithm-expression: order_${user_id % 4}

WARNING

分库分表会带来跨分片查询、分布式事务、全局主键等新问题。建议在数据量真正成为瓶颈时再考虑,不要过早分片。