目录
一、什么是分库分表
1.1 基本概念
把原来存储在一个数据库中的数据,分开存入多个数据库中
1.2 实例
公司购买了消费核心系统,如下:
由于业务扩大,将原有系统拆分成一个个微服务,增加系统灵活性和稳定性,如下:
问题:性能和存储上不能满足需求,因为数据库支持的并发访问量是有限的,因此将数据库进行拆分
由于数据量的激增,同一个数据库也需要进行拆分,用以缓解压力:
上面的拆分具有以下好处:
1. 提升数据的访问速度
2. 缓解数据库的压力
1.3 那么一张表数据量多大时,才需要分库分表呢?
以实际情况为准,如果字段很少,数据不多,千万条数据也可以存储;反之,如果字段很多,数据很大的话,需要进行分库分表。阿里的Java编程手册约定500w条数据时,可以进行分库分表,要尽可能不要进行分库分表
二、分库分表要怎么分?
2.1 垂直分库
问题:
1. 关联查询
2. 数据冗余
3. 分布式事务
4. 垂直切分并没有从根本上解决单表数据量过大的问题
分库要尽量避免跨库查询。如果需要跨库查询,需要反思一下分库是否合理。
2.2 水平切分
2.2.1 基本概念
水平切分可以分为单库的水平切分和跨库的水平切分
单库的水平切分:比如将用户每个月的活动使用一张表进行记录,所有的表存储在同一个数据库中
跨库的水平切分:一张表的数据放在不同的数据库中存储,比如客户有一亿条数据,我们每个数据库存储500w条数据。
2.2.2 问题:
1. 翻页查询问题。如果数据分别存储在不同的表中,limit要怎么处理(中间件可以处理解决)
2. 全局ID的问题
- 数据库专门有一个sequence表,用于分别ID
- UUID:重复概率极小,但是不建议用他作为主键,因为他不能排序
- 雪花算法:趋势递增(不是顺序递增,增加安全性)
- Redis
- ZK
3. ORM如何选择数据源——sharding-jdbc
常见的分片算法:
- 随机——容易分配不均
- 哈希——一般非整形的数据会先哈希再取模
- 取模
- Range
- 日期
- 扩容和缩容
mycat中间件中包含了上述分片算法
三、sharding-jdbc 分表实例
sharding-jdbc:
https://shardingsphere.apache.org/document/legacy/4.x/document/cn/overview/