Skip to content

TDSQL 垂直拆分与水平拆分

垂直拆分

垂直拆分定义

将一个表按照列的方式拆分成多个表,每个表包含原表的一部分列。

垂直拆分原则

  • 按照业务功能拆分
  • 按照访问频率拆分
  • 按照数据类型拆分
  • 考虑数据的关联性

垂直拆分优点

  • 减少查询时的IO开销
  • 提高缓存命中率
  • 便于维护和扩展
  • 可以针对不同表进行优化

垂直拆分缺点

  • 增加表之间的关联查询
  • 事务处理复杂度增加
  • 开发和维护成本提高

垂直拆分案例

原表结构

sql
CREATE TABLE users (
    id INT PRIMARY KEY,
    username VARCHAR(50),
    password VARCHAR(100),
    email VARCHAR(100),
    phone VARCHAR(20),
    address TEXT,
    created_at DATETIME,
    updated_at DATETIME,
    last_login DATETIME,
    status TINYINT,
    avatar_url VARCHAR(255),
    bio TEXT
);

拆分后表结构

sql
-- 核心用户表
CREATE TABLE user_core (
    id INT PRIMARY KEY,
    username VARCHAR(50),
    password VARCHAR(100),
    email VARCHAR(100),
    phone VARCHAR(20),
    status TINYINT,
    created_at DATETIME,
    updated_at DATETIME
);

-- 用户扩展信息表
CREATE TABLE user_profile (
    user_id INT PRIMARY KEY,
    address TEXT,
    avatar_url VARCHAR(255),
    bio TEXT,
    FOREIGN KEY (user_id) REFERENCES user_core(id)
);

-- 用户登录记录表
CREATE TABLE user_login (
    user_id INT PRIMARY KEY,
    last_login DATETIME,
    login_count INT DEFAULT 0,
    FOREIGN KEY (user_id) REFERENCES user_core(id)
);

水平拆分

水平拆分定义

将一个表按照行的方式拆分成多个表,每个表包含原表的一部分行数据。

水平拆分原则

  • 选择合适的拆分键
  • 确保数据分布均匀
  • 考虑查询模式
  • 便于扩展

水平拆分优点

  • 解决单表数据量过大问题
  • 提高查询性能
  • 支持高并发访问
  • 便于数据管理和维护

水平拆分缺点

  • 增加查询复杂度
  • 事务处理困难
  • 跨分片查询性能下降
  • 数据迁移和扩容复杂

水平拆分策略

范围拆分

  • 按照时间范围或数值范围拆分
  • 优点:简单易实现,适合趋势数据
  • 缺点:数据分布可能不均匀

哈希拆分

  • 根据拆分键的哈希值进行拆分
  • 优点:数据分布均匀
  • 缺点:扩容时需要重新哈希

列表拆分

  • 按照特定的列表值进行拆分
  • 优点:适合特定业务场景
  • 缺点:需要手动维护列表

复合拆分

  • 结合多种拆分策略
  • 优点:灵活适应复杂业务场景
  • 缺点:设计和实现复杂

水平拆分案例

按用户ID哈希拆分

sql
-- 分片1:user_id % 4 = 0
CREATE TABLE orders_0 (
    id INT PRIMARY KEY,
    user_id INT,
    product_id INT,
    amount DECIMAL(10,2),
    status TINYINT,
    created_at DATETIME
);

-- 分片2:user_id % 4 = 1
CREATE TABLE orders_1 (
    id INT PRIMARY KEY,
    user_id INT,
    product_id INT,
    amount DECIMAL(10,2),
    status TINYINT,
    created_at DATETIME
);

-- 分片3:user_id % 4 = 2
CREATE TABLE orders_2 (
    id INT PRIMARY KEY,
    user_id INT,
    product_id INT,
    amount DECIMAL(10,2),
    status TINYINT,
    created_at DATETIME
);

-- 分片4:user_id % 4 = 3
CREATE TABLE orders_3 (
    id INT PRIMARY KEY,
    user_id INT,
    product_id INT,
    amount DECIMAL(10,2),
    status TINYINT,
    created_at DATETIME
);

拆分实现方式

应用层拆分

  • 在应用程序中实现拆分逻辑
  • 优点:灵活可控,性能较好
  • 缺点:开发和维护成本高

中间件层拆分

  • 使用数据库中间件(如TDSQL Proxy)实现拆分
  • 优点:对应用透明,易于维护
  • 缺点:引入中间件开销

数据库层拆分

  • 利用数据库自身的分区功能
  • 优点:实现简单,管理方便
  • 缺点:扩展性有限

拆分注意事项

事务处理

  • 跨分片事务处理复杂
  • 可以使用分布式事务或最终一致性
  • 尽量避免跨分片事务

关联查询

  • 跨分片关联查询性能差
  • 可以使用数据冗余或应用层拼接
  • 设计时考虑减少关联查询

数据迁移

  • 初始数据迁移策略
  • 在线扩容时的数据迁移
  • 数据一致性保证

主键生成

  • 全局唯一主键生成策略
  • 可以使用UUID、雪花算法等
  • 避免使用自增主键

分片键选择

  • 选择访问频率高的字段
  • 确保数据分布均匀
  • 考虑查询模式
  • 避免热点数据

拆分最佳实践

设计原则

  • 先垂直拆分,再水平拆分
  • 拆分粒度适中
  • 考虑未来3-5年的业务增长
  • 避免过度设计

性能优化

  • 合理使用缓存
  • 优化查询语句
  • 定期进行数据归档
  • 监控和调优

运维管理

  • 建立完善的监控体系
  • 制定数据备份和恢复策略
  • 定期进行性能测试
  • 建立应急预案

拆分工具

TDSQL 内置工具

  • TDSQL Console:可视化拆分管理
  • TDSQL Proxy:透明的分片代理
  • TDSQL Migration Tool:数据迁移工具

第三方工具

  • MyCAT:开源数据库中间件
  • ShardingSphere:分布式数据库生态
  • Canal:数据同步工具

常见问题(FAQ)

Q1: 如何选择垂直拆分还是水平拆分?

A1: 根据业务场景和数据特点选择:

  • 垂直拆分适合:表结构复杂、列数量多、访问频率差异大
  • 水平拆分适合:单表数据量过大、查询性能下降、需要高并发访问

Q2: 如何处理跨分片事务?

A2: 处理跨分片事务的方法:

  • 使用分布式事务(如XA协议)
  • 采用最终一致性方案
  • 设计时避免跨分片事务
  • 使用本地消息表或事务消息

Q3: 如何选择合适的分片键?

A3: 选择分片键的原则:

  • 访问频率高的字段
  • 能使数据分布均匀
  • 符合查询模式
  • 避免热点数据
  • 考虑业务增长

Q4: 拆分后如何进行数据迁移?

A4: 数据迁移的步骤:

  • 设计迁移方案
  • 进行数据备份
  • 使用迁移工具进行数据同步
  • 验证数据一致性
  • 切换业务流量

Q5: 如何处理拆分后的关联查询?

A5: 处理关联查询的方法:

  • 数据冗余:在分片表中冗余关联数据
  • 应用层拼接:在应用程序中进行数据拼接
  • 全局表:将公共数据放入全局表
  • 避免关联查询:重新设计数据模型

Q6: 如何进行拆分后的扩容?

A6: 扩容的方法:

  • 预分片:提前规划足够的分片
  • 在线扩容:使用中间件支持的在线扩容功能
  • 双写迁移:同时写入新旧分片,然后切换
  • 数据重分布:重新计算分片规则