外观
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: 扩容的方法:
- 预分片:提前规划足够的分片
- 在线扩容:使用中间件支持的在线扩容功能
- 双写迁移:同时写入新旧分片,然后切换
- 数据重分布:重新计算分片规则
