环境信息
基于C#语言、SqlServer数据库。
本次分表的目的
问题现状
业务系统随着时间的进展,数据越来越多,系统运行越加缓慢,所有数据存在一个表中,单表数据量已经到达几个亿(笔者项目单表突破5亿条),并且伴随业务增长字段仍可能继续增加。对数据进行规范存储,提高系统性能的需求已经刻不容缓。
解决方案
对数据进行逻辑表分,将数据按季度、月度进行拆分。
其他方案
分区表(与本方案不冲突,可选择一种进行实施,也可以结合使用)
总体流程
通过特定的时任务(数据库计划,或者windows任务,或者其他工具;笔者项目采用自己开发的windows服务)进行数据分表拆分。
具体步骤
- 建立索引表;
索引记录分表的记录,查询时通过索引表快速找到数据所在的分表。
- 建立分表相关存储过程(笔者建立了7个存储过程,相互调用),如下:
- 复制源表主键
- 复制表结构及索引
- 建立分表
- 迁移数据
- 批量迁移数据(历史数据迁移入口)
- 根据营业日期迁移数据(营业时迁移数据入口)
- 获取分表结果集(查询数据入口)
- 利用工具进行历史数据分表(可利开源的ETL工具:Kettle,笔者是自己开发的一个工具),此处特别注意大批量数据操作带来的影响。
- 建立定时任务,定时执行存储过程,以执行日常营业数据的分表;
源表中的数据保存期限
源表保留若干天的数据冗余,以便数据迁移出现问题可进行问题分析,特别是在项目刚实施阶段,以避免分表造成数据遗漏。
注意点
分表的作用
- 数据量小的系统,分表对性能的提升微乎其微;只有当数据量大到一定等级的时候,分表的优势才能有所体现;
- 分表还有一个重要的思维:对数据的管理,按特定的维度将数据保存在不同的集合中;
- 如果磁盘成为瓶颈,建议采用分区表,将数据拆分到不同的磁盘,也可通过多个磁盘提高计算能力。
对于单表数据量达多少可以分表的一些建议
笔者经过一番调查,给出如下关系型数据库单表记录数建议:
|
mysql |
sqlserver |
oracle |
通常建议不超过 |
500W |
500W |
500W |
最大建议不超过 |
2000W |
2000W |
5000W |
数据库性能与服务器配置、索引、执行的sql复杂度有关,以上仅为参考值。