分库分表总结


 

为什么要使用分库分表?什么时候使用分库分表?

关系数据库的性能容易成为系统性能的瓶颈,读写分离分散了数据库的读写压力,但并没有分散存储压力,当数据量达到千万甚至上亿时

  • 数据量太大,读写性能下降,即使使用索引,索引也会很大,性能也会下降
  • 数据库文件很大,备份、恢复耗时长
  • 数据库文件越大,数据丢失风险越高,发生故障时数据丢失量往往很大
     

当数据库并发量很大、存储的数据量很大时,往往需要分库分表,分担单个数据库的存储压力、读写压力,提高数据库性能。

有2种切分策略:水平切分、垂直(纵向)切分。

 

垂直切分

垂直分库

根据数据表的耦合度进行拆分,将同一数据库中关联度低的表拆分出来,放在新的数据库中。
 

垂直分表

①如果某张表的字段很多,可以把不常用的字段拆分出来,单独放到一张新表中,实现冷热数据分离。

②或者把内容较多、较大的字段拆分出来。数据库底层通过数据页存储数据,一条记录占用空间很大会导致跨页,拉低性能。
 

在字段很多的情况下,通过大表拆小表,方便开发、维护,也能避免跨页问题。

另外,数据库以行为单位将数据加载到内存,表中字段内容越短,能加载到内存的数据(记录数)越多。冷热分离后,热点表中热点字段多、访问频率高,缓存命中率也就很高,大大提高了数据库的检索性能。
 

垂直切分的缺点

  • 垂直分库使原本在同一数据库中的表拆分到不同数据库(节点)中,操作不同数据库中的表要使用分布式事务,事务的使用变得复杂。另外,跨库的多表关联查询性能较差。
  • 垂直分表使原本一张表中的字段拆分到多张表中,不同表之间的操作需要多表关联查询,连接查询性能较差

总之,垂直切分提升了单表查询的性能,但增加了多表关联查询的次数。

 

水平切分

垂直切分只是减少了单表的字段数,但并没有减少单表的记录数。水平切分是将单表中的记录拆分到多张表中。
 

按新表存放位置可分为2种
  • 库内分表  将拆分出来的新表放在同一数据库中
  • 分库分表  将拆分出来的新表放在不同的数据库中

库内分表只解决了单表记录数过多的问题,但拆分出来的表竞争同一个机器的CPU、内存、网络IO,并没有减轻数据库的存储压力。

分库分表解决了单表记录数过多的问题,也分散了单个数据库的存储压力,但垮库操作要使用分布式事务,事务难度加大,跨库的多表关联查询性能较差。

水平切分都有的缺点:聚合函数、order by排序、group by分组使用不方便,要从多个子表中查数据,然后自己汇总。

 

2种记录拆分方式

1、根据范围进行拆分

eg. 根据id字段的范围进行划分,1 ~ 9999999放到一张表中,10000000~199999999放到一张表中,以此类推。

关键在于范围的选取上,分段太小会导致子表数量过多,增加维护难度;分段太大则拆分意义不大。通常,单个分段大小在100W ~ 2000W之间。
 
优点

  • 扩容方便。随着记录数的增加,可以直接使用新表来存储数据,原有数据不需要动
  • 单表大小(记录数)可控
     

2、根据hash值进行拆分

eg. 商品信息表,计算type字段的hash值,把hash值相同的字段划到同一表中,一张子表存储同一类型的商品。

 

路由表

水平切分,随着记录数的增加,子表数量会增加(变化),不能在代码中写死子表名。新建一张表作为路由表,一列存储子表名,

  • 如果是以范围拆分的,使用start_index、end_index 2列分别存储子表范围
  • 如果是以hash方式拆分的,用一列存储子表对应的常量,eg. 存储商品类型(type)。

操作数据库时,先查路由表得到记录所在子表,再去操作子表。要多查一次,降低了性能,所以除非单表记录数特别多,否则不要轻易水平分表。

就算要水平分表,子表数量也不宜太多,一方面难以维护,另一方面子表太多会导致路由表中记录数很多,查路由表时间开销大。

 

总结

分库分表,性能有提升之处,也有降低之处。分库分表的主要作用是减轻单机数据库的存储压力,性能考虑还再其次。
 

切分原则:先做垂直切分、再做水平切分。
 

比如user表,垂直切分为2张表

  • user_base:存放常用字段
  • user_extra表:存放不常用的字段

2张表中都有user_id字段,用于唯一标识记录。
 

此时还可能存在单表行数过多的问题,需要水平切分。

预估要分散到几个库中,每个库又要分散到几个表中,对user_id取模,将模值相同的记录划分到同一个库中,再对同一个库中的user_id取模,将模值相同的记录划分到同一个表中。

假设用户量1亿,每个库2500w个用户记录,需要分4个库;每张表500w条记录,每个库又分为5个表。user_id % 4得到该条记录所在的库,user_id % 5得到该条记录所在的表。

 

分库分表造成的问题|要考虑的点

  • 分布式主键(id)问题
  • 分布式事务问题,如何保证多个库中的数据一致性
  • 存在大量关联查询的问题:可以拆分查询,使用冗余字段、空间换时间。

分库分表带来的问题很复杂,不到万不得已,不要轻易分库分表。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值