数据库单表拆分问题

本期焦点问题:单一数据库内分表

本期多个项目出现了在单一数据库内分表的情况,典型的做法是:

某个表(表A)预期会有几千万乃至上亿条数据,于是在单库内拆分成若干张独立的表: A_1, A_2, A_3, … , A_n用“表名+后缀”来区分。

 

在绝大多数情况下,这并不是合适的做法,下表给出了库内分表对一些关键指标的影响:

项目

库内分表

应用开发难度

比单表高

需要管理数据的路由,跨表查询,排序等都较复杂。

未来拆库难度

比单表高

需要对多个表进行数据迁移,同时应用

表结构变更的难度

比单表高

除了耗时,还要变更多个表。

查询性能

走索引,和单表无明显差别。

全表扫描,如果并发执行,会比单表快一些。

写入性能

和单表比无明显差别

并发性能

对行锁无影响,会减少表锁冲突,但是按主键更新不加表锁。

 

从上表可以看出,库内分表提供的好处非常微小,而且在我们的业务场景下也基本用不到这些好处。但是却带来程序设计、运维等多方面的困难,

基于这些因素,我们不赞成使用库内分表这种设计方式。

 

那当库表出现以下几种情况时,如何来应对?

1.       记录数高

一般我们不建议单表出现1千万行以上的数据。如果业务上出现了这样的数据,首先要考虑的是通过归档来降低数据量。

归档可以有效把冷热温数据分开,同时,温数据还可以设计成在低级别SLA下提供服务。

 

对于不能归档的数据,主要是主数据,如用户,商品。可根据tps/qps及它们之间的比例、应用对数据一致性的要求、磁盘空间的大小来决定是做读写分离或水平拆分。

但主数据一般都是高访问量的共享数据,正常应该通过拆库来保证性能。

 

2.       慢查询

慢查询的出现不能想当然归于表的记录数太多,表的记录数和慢查询之间并没有必然的关系。慢查询出现的常见原因:

l  没有正确使用索引或索引失效,导致全表扫描了

l  表设计不合理,出现了多表Join

l  SQL本身的写法有问题,出现了大量的中间结果

l  SQL返回结果集过大

 

所以慢查询应该重点从表的设计和SQL的写法上去解决,库内分表不是一个好的方案。

 

3.       TPS/QPS

TPS高是拆库的最重要的依据,比如说一些订单表,优惠券表等大表都有数亿条数据,拆分的首要原因就是TPS撑不住了,超过6K从库就会开始有明显延迟。

如果TPS不高但QPS很高,而且对数据的一致性要求不高,可以考虑读写分离方案。

 

 

猜你喜欢

转载自breezylee.iteye.com/blog/2348583