爱陪小樱桃

导航

 

1.什么是分库分表

分库:
就是数据库分成多个数据库,部署到不同的机器上。
例如:用户表,订单表,积分表,商品表:然后分到:用户库,订单库,积分库,商品库。

分表:
一个表分成多个表
例如:订单表:分成分表1,分表2,分表3;

为什么分库:

在做任何事情之前我们都要思考,为什么做?为什么要拆分表,拆分表的原因是什么?我们不能可能无缘无故的做分库分表的。

当业务量巨大的增加,数据库就有一定的性能问题了,这时候我们要考虑拆分数据库,
1.随着业务量的增加,mysql的磁盘会有性能问题,拆成多个库,就可以降低磁盘的使用率。
2.数据库的连接数,是有控制的,太多的连接数会导致性能问题:会报错,例如:too many connection

为什么分表

如果单表数据量过大,查询和存储都会有性能问题,如果做了优化还是无法解决性能问题,这时候要考虑分表了,一般千万级别的数据,就要分表。

什么时候分库分表

对于MYSQL单标最多存储10亿级别,但是如果单表真的存储10亿性能会非常的差,一般数据量是千万级别,B+树索引的高度就会到了3层以上了,查询的时候会多查磁盘的次数,SQL会变慢。

实际阿里规定:单表超过500万,表容量2G就推荐分;

但是并不是死的,所有的都这样,要按照实际,如果我们的业务几年都打不到500万不用考虑分表的问题。

什么类型的业务考虑分库分表?

流水表,用户表,

如何选择分表键

分表键就是用来分库分表的,就是分的依据,依据哪个维度分?
按照userID,按time,按照区域;

问题分表后,用户通过非分表键怎么查询:

例如我们按照userID来分表,但是我们登录是手机号登录,怎么通过手机号进行各个表的查询呢?
1.遍历所有的表,不建议,太笨的方法。
2.将用户信息冗余同步到ES,然后通过ES查询;

如何选择分表的策略:

1.按照范围分

1.按照ID1-300万分,这样分
2.按照时间,比如**年分

  • 优点:
    有利于扩容
  • 缺点:
    -一段时间有的数据都只会出现在一个表里面,如果用户查询近期数据,肯定还是查询某一个表。

2.按照hash取模分

(字段,字段2,字段3,字段4,)作为key,对总表进行取模,把数据分散到各个表里面。hash/4
例如:hash(字段1)/4,=1,就放第一个表,得到3就放在第三个表。

  • 优点:不会存在明显的某个表过热的问题
  • 缺点:表数据量后续达到瓶颈,需要扩容比较麻烦。

3.一致性hash
接上述问题:如果开始我们只有10个表,后边需要扩充到20个,那么之前10个表的数据,就有可能被重复分配到别的表里面去。

为了解决扩容问题:需要扩容迁移,可以使用hash一致性思想来解决。

分库后,事务问题如何解决?

本地事务无效,需要使用分布式事务。

分库分表遇到join怎么办?

1.字段冗余:空间换时间,就是吧关联的字段放到主表里面,就不用去关联了。
2.全局表:比如系统所有的模块都可能会依赖到一个基础表。
3.数据抽象同步:A表a和B表b,定时将表做同步,将数据汇合,生成新的表,一般可以借助ETL工具。
4.应用层代码组装:分开多次查询,调用不同模块服务,获取到数据后,代码层进行字段计算拼装。

聚合函数问题

1.使用mycat, shardingSphere 等,这些中间件提供了跨分片查询支持,一定程度简化了操作。

分库分表后的分页问题:

1.在各个数据库节点,查询到对应的结果后,代码汇总,然后在分页。缺点:返回多数据,增大网络传输。
2.方法二:查询第一页的时候,和方案一一样,但是下一页,需要把当前最大的创建时间传过来,然后每个节点,都查询大于创建时间的一页数据,接着汇总,内存排序返回。

分布ID

数据库被分后,不能使用自身的主键生成机制,可以使用简单的UUID,或者分布式ID。

分库分表使用的中间件?

1.Sharding-JDBC
2.cobar
3.Mycat
4.Atlas
5.TDDL
6.Vitess

如何评估分库数量

对于mysql一般5千万,就非常大了,分多少,取决于处理能力。
分的少起不到优化的作用,分的过多,跨多库访问。,一般建议4-10个库。

分表要停服务?

1.开关,控制访问新的DAO层,还是老的DAO层
2.投产,开启双写,就是老表,和分表都写入,日志临时表记录新表的ID,旧表小于这个值的数据,就是要迁移的数据。
3.通过脚本,迁移
4.停止读旧表,改读新表,不要立即停止写老的,需要双写观察一段时间。
5.读写一段时间没有问题,可以停止写旧表啦。

posted on 2024-10-31 22:56  cherry小樱桃  阅读(9)  评论(0编辑  收藏  举报