分库分表基础理论

针对数据切分类型,大致可以分为:垂直(纵向)切分和水平(横向)切分两种。

垂直切分:垂直分库,垂直分表。

垂直分库按照业务类型区分:

在这里插入图片描述

垂直分表:把大表拆分成小表,一个order表有很多字段,把长度较大且不经常查询的字段拆到work_order表

 水平切分:将原表切分成,列相同,数据不同的各张小表。按不同条件分散到多个数据库中。

一张order表有2000万数据,水平切分后出来四个表,order_1、order_2、order_3、order_4,每张表数据500万,以此类推。

 水平切分又分为:库内分表,分库分表

库内分表:拆分后的表都在同一数据库,只解决了单表数据量过大的问题。

分库分表:则是将切分出来的子表,分散到不同的数据库中,从而使得单个表的数据量变小,达到分布式的效果。

优点:

解决高并发时单库数据量过大的问题,提升系统稳定性和负载能力
业务系统改造的工作量不是很大

缺点:

跨分片的事务一致性难以保证
跨库的join关联查询性能较差
扩容的难度和维护量较大,(拆分成几千张子表想想都恐怖)

数据该往哪个库的表存

分库分表以后会出现一个问题,一张表会出现在多个数据库里,到底该往哪个库的表里存呢?

1,根据取值范围

按照时间区间或ID区间来切分,举个栗子:假如我们切分的是用户表,可以定义每个库的User表里只存10000条数据,第一个库userId从1 ~ 9999,第二个库10000 ~ 20000,第三个库20001~ 30000……以此类推。

优点:

单表数据量是可控的
水平扩展简单只需增加节点即可,无需对其他分片的数据进行迁移
能快速定位要查询的数据在哪个库

缺点:由于连续分片可能存在数据热点,如果按时间字段分片,有些分片存储最近时间段内的数据,可能会被频繁的读写,而有些分片存储的历史数据,则很少被查询

2,hash取模

hash取模的方式比较常见,以user表为例,对数据库从0到N-1编号,对userId经行取模得到余数i,i=0存第一库,i=1存第二库,i=3存第三库。这样同一个用户的数据都会存在同一个库里,用userId作为条件查询就很好定位了。

优点:

数据分片相对比较均匀,不易出现某个库并发访问的问题

缺点:

但这种算法存在一些问题,当某一台机器宕机,本应该落在该数据库的请求就无法得到正确的处理,
这时宕掉的实例会被踢出集群,此时算法变成hash(userId) mod N-1,用户信息可能就不再在同一个库中。

分库分表后会有哪些坑?

1、事务一致性问题

由于表分布在不同库中,不可避免会带来跨库事务问题。一般可使用"XA协议"和"两阶段提交"处理,但是这种方式性能较差,代码开发量也比较大。

通常做法是做到最终一致性的方案,往往不苛求系统的实时一致性,只要在允许的时间段内达到最终一致性即可,可采用事务补偿的方式。

2、分页、排序的坑

日常开发中分页、排序是必备功能,而多库进行查询时limit分页、order by排序,着实让人比较头疼。

分页需按照指定字段进行排序,如果排序字段恰好是分片字段时,通过分片规则就很容易定位到分片的位置;一旦排序字段非分片字段时,就需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序,最终返回给用户,过程比较复杂。

3、全局唯一主键问题

由于分库分表后,表中的数据同时存在于多个数据库,而某个分区数据库的自增主键已经无法满足全局

唯一,所以此时一个能够生成全局唯一ID的系统是非常必要的。那么这个全局唯一ID就叫分布式ID

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值