1.分库分表
当一张表的数据达到几千万时,查询一次所花的时间会变长。数据切分可以分为:垂直切分和水平切分。
垂直切分
垂直分库
根据业务耦合性,将关联度低的不同表存储在不同的数据库。

垂直分表
一个表的多个字段分别拆成多个表,一般按字段的冷热拆分,热字段一个表,冷字段一个表,从而提升了数据库性能。

优缺点
- 解决业务系统层面的耦合,业务清晰
- 高并发场景下,垂直切分一定程度的提升IO、数据库连接数、单机硬件资源的瓶颈
- 分库后无法Join,只能通过接口聚合方式解决,提升了开发的复杂度
- 分库后分布式事务处理复杂
- 依然存在单表数据量过大的问题
水平切分
当一个应用难以再细粒度的垂直切分或切分后数据量行数巨大,存在单库读写、存储性能瓶颈,这时候就需要进行水平切分了。
水平分库
水平分表
一张表的数据不要超过1千万,如果表数据超过1千万,并且还在不断增加数据,那就可以考虑分表。
优缺点
- 不存在单库数据量过大、高并发的性能瓶颈,提升系统稳定性和负载能力
- 应用端改造较小,不需要拆分业务模块
- 跨分片的事务一致性难以保证
- 跨库的Join关联查询性能较差
- 数据多次扩展难度和维护量极大
分片规则
Hash取模分表
一般采用Hash取模的切分方式,例如:假设按goods_id分4张表。(goods_id%4 取整确定表)

- 数据分片相对比较均匀,不容易出现热点和并发访问的瓶颈。
- 后期分片集群扩容时,需要迁移旧的数据很难。
- 容易面临跨分片查询的复杂问题
数值Range分表
按照时间区间或ID区间来切分。例如:将goods_id为1-1000的记录分到第一个表,1001-2000的分到第二个表,以此类推。

- 单表大小可控
- 天然便于水平扩展,后期如果想对整个分片集群扩容时,只需要添加节点即可,无需对其他分片的数据进行迁移
- 热点数据成为性能瓶颈
一致性Hash算法
一致性Hash算法能很好的解决因为Hash取模而产生的分片集群扩容时,需要迁移旧的数据的难题。
问题
分布式事务问题
使用分布式事务中间件解决,具体是通过最终一致性还是强一致性分布式事务,看业务需求。
跨节点关联查询Join问题
切分之后数据可能分布在不同的节点上,考虑到性能,尽量避免使用Join查询。
全局表:也可看做是 “数据字典表“,就是系统中所有模块都可能依赖的一些表,为了避免跨库Join查询,可以将 这类表在每个数据库中都保存一份。这些数据通常很少会进行修改,所以也不担心一致性的问题。
字段冗余:利用空间换时间,为了性能而避免join查询。
数据组装:在系统层面,分两次查询。第一次查询的结果集中找出关联数据id,然后根据id发起第二次请求得到关联数据。最后将获得到的数据进行字段拼装。
全局主键避重问题
主键自增肯定不合理,如果用UUID那么无法做到根据主键排序,所以我们可以考虑通过雪花ID来作为数据库的主键。
跨节点分页、排序、函数问题
当排序字段是分片字段时,通过分片规则就比较容易定位到指定的分片;当排序字段非分片字段时,就变得比较复杂了。需要先在不同的分片节点中将数据进行排序并返回,然后将不同分片返回的结果集进行汇总和再次排序,最终返回给用户。
2.ShardingSphere
概述
ShardingSphere是一套开源的分布式数据库中间件解决方案组成的生态圈,它由Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar这3款相互独立的产品组成。

ShardingSphere-JDBC
ShardingSphere-Proxy
ShardingSphere-Sidecar
结果归并
将从各个数据节点获取的多数据结果集,组合成为一个结果集并正确的返回至请求客户端,称为结果归并。

遍历归并
它是最为简单的归并方式。 只需将多个数据结果集合并为一个单向链表即可。在遍历完成链表中当前数据结果集之后,将链表元素后移一位,继续遍历下一个数据结果集即可。
排序归并
hardingSphere在对排序的查询进行归并时,将每个结果集的当前数据值进行比较,并将其放入优先级队列。每次获取下一条数据时,只需将队列顶端结果集的游标下移,并根据新游标重新进入优先级排序队列找到自己的位置即可。
分组归并
聚合归并
分页归并
ShardingSphere通过装饰者模式来增加对数据结果集进行分页的能力。
