1.什么是分库分表

举个例子就是以前只有一个数据库A,里面存放了交易表和用户信息表
现在经过水平分库分表变成了:
数据库A1:里面有交易表1、用户信息表1等等
数据库A2:里面有交易表2、用户信息表2等等

2.为什么要分库分表

分库:
比如说以前一个数据库同一时间只能处理1000条连接请求,那么现在公司业务发展了,同一时间有1500条连接请求,那么这1500-500=500条请求就阻塞了,所以这时候我们就需要增加数据库来处理请求
分表:
比如说一张交易表现在数据量有十几个亿,那么在没有命中索引的情况下,sql就会全局查询,速度非常慢,这时候我们就可以将一张交易表分为多个

3.怎么样分库分表

分库分为水平分库和垂直分库:
水平分库:将表按照一定规则分配到不同库中
比如说交易表1放在A库中,交易表2放在B库中
垂直分库:按业务进行划分,实现专库专用
比如说分为用户库,交易库,订单库之类的
分表分为水平分表和垂直分表:
水平分表:将表按照一定规则分为不同的表
比如说交易表分为交易表1、交易表2
垂直分表:将一个表的的按照字段来拆分为多个表
比如说交易表里面有时间、金额、用户信息,将时间、金额划分为一个表,将用户信息划分为一个表

4.分库分表带来的问题(复杂性)

4.1事务一致性问题

举个例子A库提交成功了,B库没有提交成功,你服务器该怎么办
以前我们都是单数据库用本地事务就能搞定,多数据库的话只能使用的
解决方案是分布式事务 、最终一致性
分布式事务
二阶段提交、三阶段提交,这个比较复杂,原理就是加一个中间层去处理
本体方法表:
比如说在A、B库分别建立本地方法表,记录消息发送状态
比如说A库成功提交事务,那么通过消息队列传给B库,B库处理成功自己事务,就提交
如果B库处理失败,就提醒A库一起回滚
最终一致性
就是当前不用管是否事务一致,等到日终专门处理,也属于复杂场景

4.2跨域jion查询问题

举个例子以前查询交易表所有的数据,直接join就可以了,那么现在交易表中的数据分配到不同库中,我们应该查询不同库中的不同数据。
全局表
比如说一些平常不用修改的数据字典表,你可以直接把它设为全局表,不让它散落到不同的数据库不同的表中,直接查询既可
分段查询
比如说我要查的交易表的数据现在被分到了A库的交易表1和B库的交易表2
那么我可以先第一次查询A库的交易表1,然后封装成临时表
第二次查询B库的交易表2,同时查询临时表即可
ER分片
这个比较复杂,就是说有一些表是有关联的,那么我在分表的时候尽量将这有有关联的数据分到一个数据库中
字段冗余
比如说我要查的信息包括了A库交易表的流水号和B库用户表的名字
那么我可以为了避免跨域查询,我直接将A库交易表的字段加一个名字与用户表的名字对应即可

4.3分布式主键一致问题

以前单数据库直接用自增主键,现在多数据库如何使用自增主键
uuid
也是一种根据命名空间来生成主键的算法,它是32位
一般被抛弃
数据库生成
就是说增加一个表,里面来维护主键的信息
雪花算法
就是一种根据命名空间生成数据的算法,它是64位,来保证主键唯一

4.4排序、分页、函数计算问题

如何进行多数据库的排序、分页、函数计算
以分页为例,只能用多次查询封装成临时表解决
比如说统计交易表前十条数据,先去A库交易表1统计前十条数据
然后再去B库交易表2统计前十条数据进行对比
当要统计超多数据时,这种性能影响超级大
解决方案:
1.前台限制用户只能看多少条
2.后台批处理获取数据时,增大size,减少获取次数
3.直接走大数据平台

4.5多数据源问题

如何将多数据库中的数据获取
加一个中间件即可常用的是Mycat

4.6非主键查询问题

单数据库查询非主键,可以索引回表,
那么多数据库怎么去查询非主键数据呢
建立映射
常用的非主键查询字段直接在本地建立映射表,与主键进行对应
基因分库
建立一个函数映射,当数据按照主键分片规则进行划分时,hash/2,那么我也建立一个函数让这个非主键字段f(name)=hash/2,这就可以确定这条数据在哪里了