从 0 开始学架构
李运华
网名“华仔”,前阿里资深技术专家(P9)
152573 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 66 讲
结束语 (1讲)
结课测试 (1讲)
从 0 开始学架构
15
15
1.0x
00:00/00:00
登录|注册

15 | 高性能数据库集群:分库分表

order by操作
count()操作
join操作
路由
中间件封装
程序代码封装
复杂性
适用场景:表行数特别大的表
复杂性:表操作数量增加
适用场景:将不常用且占用大量空间的列拆分出去
小公司初创业务
成本问题
事务问题
join操作问题
实现方法
分表的复杂性
业务分库和分表的问题和适用场景
实现方法
水平分表
垂直分表
概念:将表行数特别大的表进行拆分
适用场景
问题
概念:按照业务模块将数据分散到不同的数据库服务器
总结
分表
业务分库
高性能数据库集群:分库分表

该思维导图由 AI 生成,仅供参考

上期我讲了“读写分离”,读写分离分散了数据库读写操作的压力,但没有分散存储压力,当数据量达到千万甚至上亿条的时候,单台数据库服务器的存储能力会成为系统的瓶颈,主要体现在这几个方面:
数据量太大,读写的性能会下降,即使有索引,索引也会变得很大,性能同样会下降。
数据文件会变得很大,数据库备份和恢复需要耗费很长时间。
数据文件越大,极端情况下丢失数据的风险越高(例如,机房火灾导致数据库主备机都发生故障)。
基于上述原因,单个数据库服务器存储的数据量不能太大,需要控制在一定的范围内。为了满足业务数据存储的需求,就需要将存储分散到多台数据库服务器上。
今天我来介绍常见的分散存储的方法“分库分表”,其中包括“分库”和“分表”两大类。

业务分库

业务分库指的是按照业务模块将数据分散到不同的数据库服务器。例如,一个简单的电商网站,包括用户、商品、订单三个业务模块,我们可以将用户数据、商品数据、订单数据分开放到三台不同的数据库服务器上,而不是将所有数据都放在一台数据库服务器上。
虽然业务分库能够分散存储和访问压力,但同时也带来了新的问题,接下来我进行详细分析。
1.join 操作问题
业务分库后,原本在同一个数据库中的表分散到不同数据库中,导致无法使用 SQL 的 join 查询。
例如:“查询购买了化妆品的用户中女性用户的列表”这个功能,虽然订单数据中有用户的 ID 信息,但是用户的性别数据在用户数据库中,如果在同一个库中,简单的 join 查询就能完成;但现在数据分散在两个不同的数据库中,无法做 join 查询,只能采取先从订单数据库中查询购买了化妆品的用户 ID 列表,然后再到用户数据库中查询这批用户 ID 中的女性用户列表,这样实现就比简单的 join 查询要复杂一些。
2. 事务问题
原本在同一个数据库中不同的表可以在同一个事务中修改,业务分库后,表分散到不同的数据库中,无法通过事务统一修改。虽然数据库厂商提供了一些分布式事务的解决方案(例如,MySQL 的 XA),但性能实在太低,与高性能存储的目标是相违背的。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

高性能数据库集群中的分库分表技术是解决单台数据库服务器存储能力瓶颈的重要方案。本文深入介绍了业务分库和分表技术的优势、问题及解决方案。对于初创业务,业务分库可能增加复杂性和成本,不建议一开始就进行分库;而对于成熟大公司来说,业务分库是必要的,因为已有成熟的解决方案和海量用户规模。文章还详细介绍了垂直分表和水平分表的优势、问题及适用场景。特别是水平分表后,排序操作无法在数据库中完成,需要由业务代码或数据库中间件分别查询每个子表中的数据,然后汇总进行排序。总的来说,本文对高性能数据库集群中的分库分表技术进行了深入浅出的介绍,对于想要了解该技术的读者来说,是一篇值得阅读的文章。 文章深入探讨了高性能数据库集群中的分库分表技术,重点介绍了业务分库和分表技术的优势、问题及解决方案。对于初创业务和成熟大公司,分库分表的适用性有所不同,需要根据具体情况来决定是否引入分库分表。此外,文章还详细介绍了垂直分表和水平分表的优势、问题及适用场景,特别强调了水平分表后排序操作的复杂性。总的来说,本文对分库分表技术进行了深入浅出的介绍,对于想要了解该技术的读者来说,是一篇值得阅读的文章。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《从 0 开始学架构》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(158)

  • 最新
  • 精选
  • 明日之春
    应该是这些操作依次尝试 1.做硬件优化,例如从机械硬盘改成使用固态硬盘,当然固态硬盘不适合服务器使用,只是举个例子 2.先做数据库服务器的调优操作,例如增加索引,oracle有很多的参数调整; 3.引入缓存技术,例如Redis,减少数据库压力 4.程序与数据库表优化,重构,例如根据业务逻辑对程序逻辑做优化,减少不必要的查询; 5.在这些操作都不能大幅度优化性能的情况下,不能满足将来的发展,再考虑分库分表,也要有预估性

    作者回复: 赞,写的很完善

    2018-05-31
    9
    227
  • Kongk0ng
    如果使用hash进行分表的话,为什么大多方案推荐2的n次方作为表的总数,除了收缩容易还有什么好处吗?谢谢

    作者回复: 这个是hash函数实现的一个技巧,当计算hash值的时候,普通做法是取余操作,例如h%len,但如果len是2的N次方,通过位操作性能更高,计算方式为h & (len-1)

    2018-07-10
    16
    93
  • 老师,针对mysql,发现如果字段有blob的字段,select 不写这个字段,和写这个字段,效率差异很大啊,这个是什么原因?一直没弄明白😊 ,谢谢

    作者回复: blob的字段是和行数据分开存储的,而且磁盘上并不是连续的,因此select blob字段会让磁盘进入随机IO模式

    2019-03-28
    13
    85
  • 公号-技术夜未眠
    分库分表,可以理解为是一种空间换时间的思路,同时分流了存储压力与读写压力。 数据库性能不够时,首先应该想到是否可以通过改善硬件条件等垂直扩容手段;其次可引入读写分离、缓存/NoSQL、全文检索等手段;然后,单库单表的访问仍然存在性能瓶颈,可考虑分库分表,并且分库分表可以按照业务进行垂直拆分,接着进行水平拆分。 我的问题是:当线上已经进行了分库分表的系统,需要进一步水平扩容时,有什么好的设计方案?

    作者回复: 没有太好的方案,要么一开始的分表方案就是按照id范围来设计的,要么就需要数据迁移

    2018-05-31
    3
    46
  • 刘志刚
    我们公司业务增长比较平稳,已经经历了几个过程, 1.先是最基础的主备,Oracle 扛了3年到15年,中间优化了几次硬件和数据库上的配置 2.到16年左右开始扛不住了,数据量在3千万,但是订单表列太多,导致性能开始不理想,这个时候做了一把分区,性能勉强接受,继续扛着 3.到17年之后做到18年开始做去O项目换MySQL了,顺带着分表和分区了,目前按业务,把一些非核心业务分出去其他库了,订单的库还没分,按照历史年表和热表来做的,做滚表实现的,热表数据差不多在1千万以内,现在性能还不错,历史数据用搜索聚合的,查询性能还不错! 4.到后面如果业务再持续增长的话,估计就要拆订单库了 总结一句话,分库分表要在业务需要之前一点,看数据量和业务特性!

    作者回复: 这样做没错,如果你们12年就开始分库分表,可能当时的方案也不一定适应后来的业务变化

    2018-06-06
    4
    41
  • Snway
    我们是在设计初就考虑进去了,预估单表数据容量,再考虑未来三年的数据增长,不过现在反观这种做法,感觉有点过度设计,如当初一张用户表,分了127张,2个库,然而实际数据容量根本没这么多,顶多千万级别,不仅带来存储资源浪费,也给编码带来不少复杂度!所以我还是觉得得遵循演化原则,业务真正发展起来再考虑分库分表

    作者回复: 我们也这样做过,后来受不了了又缩表😂😂😂

    2018-05-31
    3
    38
  • 鲁伊李
    分库分表的痛点大家都知道,可否介绍下解决方案…

    作者回复: 没有很好的,要么中间件要么代码中间层,业务代码处理总是很麻烦的

    2018-05-31
    2
    29
  • kylexy_0817
    其实在同一个库里做数据拆分,无需分表吧?就例如MySQL,只需要对表做分区就可以了。分表的目的主要是为后面把表分到不同的数据库实例作准备? 还有个疑问,文中提到,用户表的description等字段内容不是经常查到,所以做垂直划分可以提高查询性能,意思是,如果表中有内容较长的字段,查询的时候不查出来(不使用select *),也会有性能问题? 最后,我觉得当单实例的访问量,已达到机器的60%承载能力,就要考虑分库,而具体如何拆分,则要分析访问量主要集中在哪些表。至于分表,主要依据还是单表的数据量和查询性能。

    作者回复: 关系数据库是行存储,即使不用那一列,也会从存储读取到内存

    2018-05-31
    6
    25
  • 耶愿
    您好!请教一个问题,目前线上业务遇到一个问题,就是订单表需要在单库里分100张表,使用uid%100分的表,前端用户查数据没有问题,后台需要查天、周、月、年的统计信息,这个应该怎么实现?而且要求每行统计记录点击后可以看到该汇总信息下所有的订单记录,这个该怎么做?

    作者回复: 后台统计库不拆分,冗余一份线上数据,既可以应对复杂的统计需求,也不担心影响线上业务

    2018-12-30
    14
    20
  • FluttySage
    老师您好,分库分表后必然会遇见运营人员实时报表查询的问题。单库时,查询实现起来比较简单。 分库之后,查询就变得复杂了,请问有没有比较好的解决思路呢?

    作者回复: 数据写双份,一份给线上用,采用分库分表;一份给运营,不分库分表

    2018-07-24
    4
    17
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部