恕我直言,我怀疑你并不会“分库分表”
随着互联网的迅速发展 , 会导致产生海量的数据 , 在数据量还比较小的时候 , 传统的处理方式是将数据存储在关系或者非关系型数据库中 , 但是随着数据量逐渐增加 , 单个数据库的表已经很难容纳所有数据 , 所以业界出现了分库分表的概念 。 利用分为知之的思想 , 完美的将数据进行了拆分 , 但是也带来了许多比较棘手的问题 , 比如引入了分布式事务、扩容等 。
数据库使用演变史
我们在应用中使用数据库主要经历以下三个阶段

文章图片
单库单表 , 应用初始阶段 , 此阶段由于数据量小于数据库承受阈值 , 对应用性能上基本没有影响 。 单库分表 , 由于数据库中的某张表数据库量过大 , 对应用的性能有了一定的影响 , 比如查询等 , 对某个表会分为table_1,table_2,table_N,将一张表拆分N张小表 。 注意此阶段磁盘容量充足 。 但是更多的是使用的数据库的分区 , 分区原理和分表原理很相似 , 比如mysqlhash的分区CREATETABLE`test_user_hash`(`user_id`bigint(19)NOTNULL,`user_name`varchar(50)NOTNULL,`ext_int`int(2)NOTNULL,`ts`bigint(19)NOTNULL,PRIMARYKEY(`user_id`,`ext_int`))ENGINE=InnoDBDEFAULTCHARSET=utf8;//Mysql分区ALTERTABLE`test_user_hash`PARTITIONBYHASH(ext_int)PARTITIONS3;复制代码mysql数据库中存储形式 , 由于上述是按3hash求余 , 所以会分三个存储文件

文章图片
分库分表 , 上述两种都无法解决时 , 出现分库分表方案 , 即将单数据库数据分散在多个数据库中 。什么情况下需要分库分表
?原则上能不分库尽量不分库 , 无法避免时或者已经有趋势显示需要分库分表 , 则使用分库分表 。
数据库的吞吐量达到瓶颈 , 需要扩多个数据库实例来提高;数据表的数据达到一定的量级 , 对应用查询等性能有了明显的影响 , 可以通过分库分表来提升性能 , 有资料显示Mysql数据库单表数据量超过5000w后对查询性能有影响为了避免后期复杂的扩容 , 提前根据数据增长的趋势预估N年后的数据量count , count/单库容量=所需数据库实例 , 属于提前规划 , 防范于未然 。常见拆分方案
常见拆分方案有两种:垂直拆分和水平拆分 , 分库分表则是一种对数据库拆分的常见解决方案 。
垂直拆分垂直拆分是根据业务特点 , 将某些有关系的表集中存储在的某个DB中 , 并且这些表的数据量一般不会过大 。 比如电商系统中有用户模块、订单模块

文章图片
水平拆分每个db中存在相同的表结构 , 根据一定的规则将数据分散在多个DB中

文章图片
分库分表实现方案
主要有以下三种实现方案
客户端分片代理实现分片分布式数据库客户端分片
客户端分片一般有两种实现方式 , 一种是应用层直接实现 , 应用层内包含分片逻辑以及分片算法等 , 与业务代码紧耦合

文章图片
应用层实现了所有逻辑 , 业务人员需要参与 。
另外一种是实现标准的JDBC协议 , 对应用提供包装过的JDBC , 对应用使用无感 , 实现逻辑作为jar , 嵌入在应用中 , 应用可以灵活的切换

文章图片
这种方式是实现标准的JDBC接口 , 对应用使用原生JDBC无影响 , 二者遵循统一规范 , 相比于第一种方式好处是与业务代码解耦 。 提高灵活性 。
代理分片
代理方式实现的方式是在应用和数据库中间增加代理层 , 独立部署 , 代理充当数据的角色 , 对应用来说使用代理就等价于数据库 , 原则上使用代理与直接使用数据库是无区别 , 但是代理毕竟不是真实的数据库 , 代理层只是解决如何充分的利用数据库资源 , 代理层实现了所有分库分表逻辑 , 包括分片规则等 , 业务人员无需关注 , 可以将更多的时间投入到业务实现逻辑中 。

文章图片
一般会在代理层外添加一层负载 。
这种方式可以让业务人员更专注于业务 , 但是复杂度相比第一种要高很多 , 增加了通讯链路 , 涉及到协议转换 , 所以会对性能相比于第一种方案有明显的损耗 , 同时对人员的要求也比较高 , 需要技术大牛来支持 , 否则一旦出现问题很难处理 。 比较耳熟的有Mycat , 由于本人基于Mycat做过深度二次开发 , 对源码有一定的了解 , 缺陷真的很 。。。。, 希望使用者仔细斟酌 , 题外话o( ̄︶ ̄)o
分布式数据库
耳熟的有TiDB , 对外提供可伸缩的架构体系 , 提供一定的分布式事务 , 可伸缩和分布式事务在内部实现中包装 , 对用者无需直接控制这些特性 , 比如TiDB提供了JDBC接口 , 应用层使用TiDB和直连MySQL数据库使用方式没什么区别
分库分表带来的问题
数据切分后 , 分散在不同的DB中 , 在使用数据库原生的Join操作时 , 存在跨库Join , 性能较差 。 引入分布式事务 , 分布式事务的一致性很难解决 。 分页 , 越往后翻页 , 查询越慢 , 比如查询100w后的10条数据 , limit1000000 , 10 。 不停机扩容难度增大后续文章会分析为了解决分库分表带来的问题 , 业界中有哪些比较成熟的解决方案 , 敬请期待...
【恕我直言,我怀疑你并不会“分库分表”】作者:掘金小勇士链接:https://juejin.im/post/5edb0d1c6fb9a047ed240e36
推荐阅读
- 台风|今年第7号台风“海高斯”生成 或将明天登陆我国广东沿海
- 科学探索|为什么科学会在需要时让我们失望?
- 人间风物志|游雍和宫:有人说这是北京必打卡景点之一,但我并不觉得非去不可
- 粤游记|旅游就该诗酒趁年华,带你一起到东京,我们玩点不一样的!
- IG能否站稳脚跟?LPL的5局4胜制,让人怀疑世界赛是否还有机会
- 师范毕业生|我国将推进师范毕业生免试认定教师资格改革
- 我为车狂|车闻 | 奔驰新星成团出道,要的就是这个范儿
- 新增|已有司机中招!均安这些路段新增电子警察
- 北京|北京卫视《我的桃花源》开播 发现京郊之美
- 聚会|小沈阳同学聚会照,现实告诉我们:有明星的聚会还是不要去了
