分库分表
MySQL存放超过几百万条数据后就有了性能问题
互连网应用:大多都是读多写少
垂直拆分
垂直分库
将一个数据库按照业务分类拆分为多个数据库。比如订单的、会员的、商品的、用户的、后台的、、
垂直分表
有的业务场景下不需要用户的所有信息,不需要查询所有字段
将用户的部分信息拆分出来到子表中
总结
- 每个库(表)的结构都不一样
- 每个库(表)的数据都(至少有一列,通常是记录 id)一样
- 每个库(表)的并集是全量数据。因为是从原来的库(表)进行拆分的,同理也可以合为全量数据。
优点:
- 拆分后业务清晰(专库专用按业务拆分,隔离性好)
- 便于维护数据
缺点:
- 受某种业务来决定、或者被限制。一个业务往往会影响到数据库的瓶颈(性能问题)。比如果双11,订单的业务操作量很大,此时会限制其他业务的使用。
- 部分业务无法关联。比如垂直分库中不同的数据库的表无法关联(join),只能通过 java 程序接口去调用,提高了开发复杂度。
水平拆分
水平分库
创建 10 个表,假设每个表最多存放 500 w条数据,根据用户 id 的最后一位决定使用那张表。
这样容量从原来的 500w 扩充到了 5000w。试想,随着业务规模扩大,总数据量超过 5000w,怎么做?
水平分表
分页怎么做?
总结
- 每个库(表)的结构都一样
- 每个表的数据都不一样
- 每个库(表)的并集是全量数据
优点:
- 单库(表)的数据保持在一定的量(减少),有助于性能提高
- 提高了系统的稳定性和负载能力。
- 分出的表的结构相同、程序的改造比较小。每个表记录都用 pojo 存储,当表字段改动时,根据业务进行垂直拆分的表需要改动的 pojo 类更多,而垂直拆分因为所有表都用一个结构,修改的 pojo 类较少。
缺点:
- 数据扩容有难度。每个库或表的存储能力都有上限,当最初水平拆分的表或库存满后,扩容很困难。
垂直拆分和水平拆分
垂直拆分:按字段进行拆分。少表多字段拆成多表少字段。
水平拆分:按照数据(内容)拆分。比如 id 尾号为 1 放在 db_1
库,id 尾号为 2 放在 db_2
库、、
前期垂直拆分,后期水平拆分。
前期主要做业务的拆分,分库更加直观
后期主要做数据的拆分。
分库分表带来的问题
- 增加了开发成本和维护成本。相比于单表单库来说。。
- 跨库join查询。
- 分布式事务。原来的 ACID。。
- 分布式全局唯一 ID,需要使用程序设计 ID
开源框架
mycat
、shardingsphere
、tddl
、mysql-proxy
等等
分类:
- JDBC 应用层。
shardingsphere
、tddl
。在程序中实现 - PROXY 代理层。
mycat
、mysql-proxy
。
JDBC 应用层分片,代表 shardingsphere
(之前叫 Sharding-JDBC
) ,底层原理:
以前的 shardings-jdbc 是基于 jdbc 的,只能通过 java 语言使用
目前支持 proxy分片 https://shardingsphere.apache.org/index_zh.html
Proxy代理层分片,MyCat
比较:
JDBC应用层分片
优点:
- 性能好
- 支持跨数据库。
缺点:
- 增加了开发难度。需要依赖 jar 包,需要修改配置
- 只支持 Java 语言使用。
Proxy代理层分片
优点:
- 可供多种语言使用。python、c、php、、、
- 开发无感知。逻辑在代理层实现,对程序员开发要求降低,不用关心背后的节点,开发只用面向代理层,像一个黑盒子。
缺点:
- 性能下降。增加了代理层,增加了数据传递次数
- 只支持 mysql,不支持 oracle。
实战
参考
https://www.bilibili.com/video/BV1pQ4y1r7FV?p=1
博客:
https://blog.csdn.net/azhuyangjun/article/details/86976568