Mysql——分库分表
目录
分库分表
唯一主键问题
常见的分片算法
分库分表后带来的问题
分库主要解决的是并发量大的问题。数据库的连接数是有限,当数据库的读或者写的QPS过高,导致数据库连接数不足,需要考虑分库了,通过增加数据库实例的方式来提供更多的可用数据库链接,从而提升系统的并发度。
分表主要解决的是数据量大的问题。单表数据量非常大,但并发不高,数据量连接还够,但存储和查询的性能遇到了瓶颈了,做了很多优化之后还是无法提升效率,就需要考虑做分表。
那么,当你的数据库链接也不够了,并且单表数据量也很大导致查询比较慢的时候,就需要做既分库又分表了。
分库分表
分库是把一个数据库,按实际场景切分多个库,再将数据表分散到多个库中。
分表是把一个数据库中的数据表拆分成多张表,防止单表过大。
划分方式一般有垂直划分和水平划分两种
- 如果把一张表中某一条记录的多个字段,拆分到多张表中,这种就是垂直划分。
- 垂直划分的结果是数据库表中的数据的字段数会变少,使得每一个单表中的数据的存储有所下降。比如我可以把商品详情信息、价格信息、库存信息等等分别拆分到不同的表中。
- 如果把一张表中的不同的记录分别放到不同的表中,这种就是水平划分。
- 水平划分的结果是数据库表中的数据会分散到多张分表中,使得每一个单表中的数据的条数都有所下降。比如我们可以把不同的用户的订单分表拆分放到不同的表中。
分库分表采用服务级中间件来实现,ShardingSphere、TDDL、Mycat。
唯一主键问题
为什么要用全局唯一主键
- 分库分表后,数据被分散到多个数据库和表中,如果每个数据库或表使用本地自增主键,可能会导致主键冲突。
- 确保数据迁移或数据合并后的数据不会出现主键冲突。
- 全局唯一主键可以简化分布式事务的管理,确保在多个分片中操作的数据主键唯一。
常见的全局唯一主键生成策略
- UUID
- UUID 很好地满足了全局唯一,但UUID作为数据库主键太长了(36 位的字符串)会导致比较大的存储开销,且UUID 是无序的,会降低数据库的写入性能。
- Snowflake 算法
- 雪花算法也是比较常用的一种分布式ID的生成方式,它具有全局唯一、有序递增、高可用的特点。
- 雪花算法生成的主键主要由 4 部分组成,1bit符号位、41bit时间戳位、10bit工作进程位以及 12bit 序列号位。
- 时间戳占用41bit,精确到毫秒,总共可以容纳约69年的时间。
- 工作进程位占用10bit,其中高位5bit是数据中心ID,低位5bit是工作节点ID,做多可以容纳1024个节点。
- 序列号占用12bit,每个节点每毫秒0开始不断累加,最多可以累加到4095,一共可以产生4096个ID。
- 所以,一个雪花算法可以在同一毫秒内最多可以生成1024 X 4096 = 4194304个唯一的ID
- 雪花算法生成的主键主要由 4 部分组成,1bit符号位、41bit时间戳位、10bit工作进程位以及 12bit 序列号位。
- 缺点
- 依赖系统时钟
- 存在时间误差或时钟回拨、时区不一致,导致生成重复 ID 或生成的 ID 顺序不一致。
- 中心化依赖
- 需要一个中心化的服务来生成 ID。
- 依赖系统时钟
- 雪花算法也是比较常用的一种分布式ID的生成方式,它具有全局唯一、有序递增、高可用的特点。
常见的分片算法
数据分片就是按照一定的规则,将数据集划分成相互独立正交的数据子集。然后将数据子集分布到不同的节点上,通过设计合理的数据分片规则,可将系统中的数据分布在不同的物理数据库中,达到提升应用系统数据处理速度的目的。
基于数据范围分片
- 根据数据的某个属性(如时间、ID等)进行范围划分,将数据分配到不同的分片中。
- 可能存在热点数据,导致数据分布不均匀。
Hash分片
- 使用哈希函数将数据分配到不同的分片中。
- 哈希算法的好处在于均匀分布数据,但是当节点增加或减少时,会导致数据大规模迁移,影响性能。
- 通过对数据的Key进行哈希计算,然后对总的节点个数取余,以确定数据存储的节点。
一致性Hash分片
- 使用一致性哈希算法将数据分配到不同的分片中。
- 一致性Hash算法可以很好地解决增加和删除节点时数据迁移的问题。
- 它将整个Hash值空间组织成一个虚拟的圆环,将节点的IP地址或主机名进行哈希取值后放置在环上。当需要确定某个Key存储在哪个节点时,对Key进行哈希取值,确定在环上的位置,然后顺时针找到第一个节点作为目标节点。这种方法可以减少节点增减时对数据迁移的影响。
分库分表后带来的问题
- 分布式事务问题
- 跨库关联查询问题
- 跨库跨表的合并和排序问题