来自:DBAplus社群

作者介绍

宇文湛泉,现任金融行业核心业务系统DBA,主要涉及Oracle、DB2、Cassandra等数据库开发工作。

数据库分区,我觉得是一个称得上“伟大”的数据库存储结构概念。

如果说,一个编程者(并非一个职业DBA)除了关注表结构本身以外,分区,可能就是所需要关注的最靠近底层的一个数据库的设计。

例如像数据库的表空间这样的概念,通常一个普通开发人员,就未必会去关注。但是分区概念却不一样,因为它与应用场景结合更加紧密。比如,按时间、按地区、按类别分区,等等。

我猜测很多人是不赞同「数据库分区是个“伟大”的概念」这个观点的。原因是,我翻阅了各种市面上主流数据库的书籍,入门级的如《XX数据库从入门到删库跑路》,看起来高端的如《XX数据库的技术内幕》,大部分书籍在介绍分区的内容的时候,都没有给很大的篇幅。

甚至有好几本书上,就这么简单的来了一句:对于一个很大的表,如果每次搜索都对全表进行扫描,会很耗时间,如果分区了之后,只要访问某个分区就会很快。

这难道不是一种误导么?分区真的能这么简单就讲清楚吗?我觉得当然不是,所以本文的内容就是想说说我认为的,分区的重要和伟大之处。

一、数据库为什么要有分区?

在《孙子兵法》的第五篇 —《兵势篇》中,孙子曰:凡治众如治寡,分数是也。斗众如斗寡,形名是也。

说人话:凡是在管理很大的数据库表时就和管理小的数据库表时一样,把它分区就好了;发挥好所有分区的功能就和发挥好其中一个分区的功能一样,他们能有一个统一的表名,可以使用统一的SQL语句来调度就好了。

上面这段话,从分号隔开,可以分成上下两句。那么“伟大”是在于前半句还是后半句呢?显然是后半句。为啥?你把人分了容易,但是你要把茫茫多的已经分开的人,指挥得像一个人一样,这件事情就伟大了。

1、考虑隔离与瓶颈

好,先讨论上半句,分治的思想。我常常遇到这样的对话场景。

场景一:

对话者:“我们的数据太大了,我们分表吧!”

我:“为什么不用分区呢?”

对话者:“分区可以解决吗?”(请自己脑补不信任的眼神和质疑的语气)

场景二:

演讲者:“我们考虑用最先进的分库技术理念来解决这个瓶颈”。

众人投去了羡慕嫉妒而又膜拜的眼神,等待着大神讲出华丽又牛叉的方案。

我:“这里有个瓶颈,我们需要给这个表分区。”

众人轻视又不懈说,好的,那分一下吧。

其实无论是分区、分表还是分库,我们都需要围绕两个重要概念,一是隔离,一是瓶颈。

在场景一种,为什么使用者要求分表呢?常见的情况中,例如,我这两个表,虽然结构一样,但是我一个是北京的数据,一个是上海的数据。如果北京的数据坏了,或者,我在对北京的数据进行奇奇怪怪的操作的时候,我需要对上海的数据完全没有影响,这就是所谓隔离。

又比如,可能全国的数据放在一起量太大,交易量太多,出现了,磁盘、IO、网络、CPU等撑不住的情况,这就是所谓瓶颈。

分区、分表、分库满足的是不同的隔离级别,以及解决不同的瓶颈。但是,他们的思想是非常接近的。

2、Partition与Sharding

Sharding这个词(通常译为分片),可以说是自带高贵的属性。每当与人讨论数据库技术,一聊到Sharding,就有一种自然而然上档次的感觉。

而且,它有很多好朋友,说出来各个华丽无比,比如分布式、集群、大数据等等。

而Partition这个词,虽然从很多角度上来看,都很类似于Sharding,或者说它们都是从“分数是也”的理念而来。但就是感觉LOW。

为啥?按我的理解,因为Partition的实现是由DBMS来完成的,使用者没感觉。而Sharding往往需要程序,设计模式,乃至整个架构的设计围绕着它服务,十分有存在感。

那它们在实际运用的时候有区别吗?当然有!那么什么时候应该Sharding,什么时候应该Partition呢?

我个人觉得Sharding的使用有两种情况,第一种叫没钱的时候,第二种是Partition用到极致,也搞不定的时候。

那么Partition什么时候搞不定呢?又有两种,一种叫没钱的时候,第二种叫超过了当今世上的硬件极限(买最贵的设备都抗不住)的时候。

1)没钱的时候

我们细细思量可以发现,分库分表这个套路在什么数据库上用的范围最广?或者你在什么地方见得会比较多?我觉得通常会指到同一个地方,叫MySQL。

虽然它有各种各样华丽的马甲,比如腾讯的TDSQL。为什么要用MySQL?因为开源免费。什么?InnoDB也很强大?如果明天Oracle开源免费,你选型的时候还会选MySQL?

不扯远了,MySQL为啥有那么多分库分表呢?我认为真相只有这一个。因为5.1版之前,MySQL不支持分区。这就是我说的第一种情况,叫没钱的时候,Oracle、SQL Server、DB2我通通买不起。好了,下一个免费的MySQL,做分库分表。

抛开玩笑的内容,Partition确实有解决不掉瓶颈需要使用分库分表的时候。但是,一个成熟的数据库使用者不应该滥用分库分表。这就是所谓DBA界分库铁律第一条,我非常赞同,叫做:能不分,就不分。然后,说说,第二种,Partition用到了极致的场景。

2)超过当前硬件极限

简单的说,我买了个Oracle,但是我的系统TPS要1万。在X86上跑Oracle,撑不住怎么办?

那么出路两条,第一条,Exadata了解一下?IBM主机买一台?买不起,好,我们在MySQL,或者X86上用Oracle做分库分表,这就是第二类里面的没钱的时候。

还有一种就是Exadata、IBM主机撑不住,所谓超越了地球上科技产品的极限,反正我没见过。

3、分库、分表、分区的使用场景

看到这里,是不是觉得扯淡内容太多了。到底什么情况分区?什么情况分表?什么时候分库呢?还是那句话,第一看隔离级别,第二看瓶颈。前一段主要说的是瓶颈场景,那么从隔离级别上来看呢?

1)分库选择

两份结构一样的数据。但他属于两个客户,客户说,我有监管要求,我不能把数据和别人的数据放在一起,必须绝对的隔离,有严格的访问控制,别人根本不能有我的DB服务器的登陆权限。

这就要求,数据在数据库层面就完全的隔开,就可以用分库。

2)分表选择

如果说我是一个云提供商,两个客户都用我的客户,他们分别有自己的用户(Schema),他们允许和他人共用数据库服务器,但是,严禁其他人使用归属于他的数据库表。

那么这时候,可以分表。

3)分区选择

如果,两份数据要求简单的隔离,相互处理不影响就可以了,有时候,我还希望一个用户一条SQL,就能对比分析他们的差异。

那这时候,分区就是一个极佳的选择。

二、数字库分区的优势

接下来讲后半部分,斗众如斗寡,形名是也。

1、分区的同时处理掉技术关口

斗众如斗寡,这句话讲起来简单,实现起来可不是那么简单。在主流的DBMS里面,不同的分区意味着不同的对象(如Oracle中,不同的Segment,DB2分区表不同分区对应数据文件)。

不夸张的说,很多数据库中间件产品,在反复纠缠、实现的内容,其本身就是主流DBMS在分区时要处理掉的技术关口。

比如有:跨库的SQL重写,一个运行在分布式场景的SQL,需要被中间件重写成多个SQL,丢到多个库去执行。尤其是,跨库的连结、聚合(包括Max、Min、Sum、Count)。其实在多分区的时候,一样存在这样的问题。

如果说这个问题,不太容易被开发者所关注到。再举一个例子:全局/本地索引。

在DBMS中,全局索引通常是要在设计上有所回避的。一般数据表一旦分区,意味着数据量比较大。例如最常见的B树索引,全局索引意味索引层次多,查询速度慢。

但是当无论如何,我在查询时,无法送入分区KEY时,全局索引总归还是最后的选择。而在分布式场景里,没有分库KEY就会非常尴尬,要么查不了,要么就要遍历所有的库,这个代价几乎就是不可接受的。

2、分区与优化密不可分

分区和分库面临的很多问题都存在着巨大的相似之处,开发者总是会重视分库所面临问题和困难,然而普遍会轻视分区可能带来的副作用。

我常常被质问,数据多了,为什么不加分区!?并发有冲突,为什么不加分区!?程序速度慢了,为什么不加分区!?PS:这一系列的质问,同样适用于为什么不加索引系列。

这种轻视源自于,主流DBMS系统对分区功能的很好的支撑。作为DBA,比较害怕的是有人懂一点数据库,且特别自信的站在他自己立场来和我讨论。

有一些开发者传递给我一个理念,分区多比分区少要好。只要用了分区,就能更快,至少不可能更差!开发者在说起这些的时候,非常的自信。

其实,在我看来分区设计和查询优化是密切相关的。分区设计一定是与特定的查询场景匹配,才能达到好的结果。

比如之前提到的没有分区列送入的查询需要逐个遍历每个分区,再比如说Hash分区后的范围查找。

Oracle中索引的Hash分区,在大规模的高并发插入的数据库表上应用十分常见,因为这种场景非常容易产生冲突事件 ,使用Hash分区之后,可以极大的缓解。然而这也挖下了一个坑,那就是这个索引上的范围查找就变得不那么理想。

由此推论,分区上可以能遇到的大坑,其实在分库的场景同样使用。

比如说,做了分库,却发现交易的业务场景拿不到Sharding Key。采用了Hash的算法,算Sharding Key,又突然发现有个交易要范围查Sharding Key,以至于可能要去各个库兜一圈。

分区面对的坑,可以说在分库场景下,是急剧放大了。所以,不可以随意滥用分区,更加不可以随便乱分库。

3、容错率提高

反过来讲,我为何在开篇说分区十分伟大,尤其是Oracle。在你违背了种种优化原则之后,做了NPI,做了跨分区的JOIN等等。尽管有性能上的损失,无论如何,数据库都帮你把那些复杂的工作给完成了。

当你的需求不是实时响应时,这些奇奇怪怪的跨分区要解决的问题,Rdbms都还是透明的把这些工作给你做完了,这怎么能不说它是伟大的呢?这一点我想那些开发分布式数据库中间件的人,最能认同。

三、写在最后

最后写到这里,作为一个DBA,我特别希望给程序开发者传递一个理念,那就是这世界上一定没有一个完美的优化方案。

你要一个表,又能高并发插入,又能做各种各样高效的查询,一会范围,一会模糊。我只想说,这是不可能的。所有优化方案都是以牺牲某一种性能来换另一种性能。

而DBA的职责,就是搞清楚业务需要什么,不需要什么。牺牲掉不需要的功能,换取需要的功能,甚至于牺牲不常用的功能,换取优异的常用功能。这其实就是完美的方案,分区也不例外。

在本文的最后,我想留一个我一直困惑的问题。在我看了无数篇分库分表放在一起的文章和帖子之后,我开始怀疑人生了。

我很想知道,无论在什么RDBMS中,是不是真的有应该采用分表,而不适合采用分区的场景呢?这个场景用分表解决了什么问题,是不可以依靠分区来解决的,欢迎留言。

长按订阅更多精彩▼

特别推荐一个分享架构+算法的公众号:

如有收获,点个在看,诚挚感谢

早在公元前五百年,孙子就参透了数据库分区的真谛相关推荐

  1. 武侯祠:一千五百年的沉思

                     武侯祠:一千五百年的沉思     中国历史上有无数个名人,但没有谁能像诸葛亮这样引起人们长久不衰的怀念:中国大地上有无数座祠堂,没有那一座能像成都武侯祠这样,让人生无 ...

  2. 【C++】公元前五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?请设计一个“高效”的算法求解。

    题目分析 公元前五世纪,我国古代数学家张丘建在<算经>一书中提出了"百鸡问题":鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一.百钱买百鸡,问鸡翁.鸡母.鸡雏各几何?请设计一 ...

  3. 每月一书(202111):《五百年来王阳明》

    现在是每月一书的时间,本月阅读的是<五百年来王阳明>,作者是郦波. 书中的内容以王阳明的生平为主线,在其中插入了心学的内容,包含心学的产生与发展.内容以小故事的形式分开介绍,因此读书的时候 ...

  4. 五百年春光明媚之重建亚历山大图书馆谭

    五百年春光明媚之重建亚历山大图书馆谭 谭理事 成都的春天真正漂亮,单是花就谭也谭不完. 二月三圣的梅花刚刚开过,三月龙泉的桃花映红了脸,四月青白江的樱花节要谢幕了,花儿躲躲,就是躲不开游人如织,结果就 ...

  5. 五百年龙池涅槃之长岛人的长江大旱谭

    五百年龙池涅槃之长岛人的长江大旱谭 谭理事 影子:在山东长岛发现古长人化石. 三峡 这长江上有了三峡,就点亮了大半个中国.毛大爷"高峡出平湖"的愿望终于实现.这么好的事情,省去了那 ...

  6. 五百年的回眸才换来今生的擦肩而过!

    这句话是从这个故事来的吧: 货运代理.第三方物流.贸易公司.货运 有个年轻美丽的女孩,出身豪门,家产丰厚,又多才多艺,日子过得很好. 货运代理.第三方物流.贸易公司.货运 媒婆也快把她家的门槛给踩 ...

  7. 五百年的修行只为一霎的回眸

    有个年轻美丽的女孩,出身豪门,家产丰厚,又多才多艺,日子过得很好.   媒婆也快把她家的门槛给踩烂了,但她一直不想结婚,因为她觉得还没见到她真正想要嫁的那个男孩.  直到有一天,她去一个庙会散心, ...

  8. 佛说五百年的回眸才换来今生的擦肩而过!(zt)

    有个年轻美丽的女孩,出身豪门,家产丰厚,又多才多艺,日子过得很好. ?? 媒婆也快把她家的门槛给踩烂了,但她一直不想结婚,因为她觉得还没见到她真正想要嫁的那个男孩. 直到有一天,她去一个庙会散心,于万 ...

  9. 五百年前王阳明的优秀读后感作文2100字

    五百年前王阳明的优秀读后感作文2100字: 台风过境,微启小窗,但见晴空昏黑,欣闻竹树群唱,喜嗅万物盎然之气,悦感清凉顿悟之风语,于书桌台灯下置一册郦波老师所著<五百年前王阳明>,读来细细 ...

最新文章

  1. 重磅直播|结构光之相移法+格雷码技术详解
  2. golang struct 动态创建
  3. 2018总结及2019计划
  4. Caffe代码导读(1):Protobuf例子
  5. if you are alone with your mac connected to Internet
  6. 你可能不知道的按位与、或运算技巧
  7. matlab 一元线性微分,怎样用matlab求一元线性函数极值
  8. Delphi单元文件引用名称问题
  9. MAC读写NTFS移动硬盘的解决办法
  10. 2019蓝桥:2019拆分为平方和问题
  11. android如何阻塞主线程,Android主线程阻塞WebView线程
  12. vscode latex 英文语法拼写检查
  13. CMMI体系建设的目的和意义
  14. 愿你历尽千帆,归来仍少年
  15. 我的测试入门——需求分析与用例编写
  16. win10更改计算机dns,w10怎么修改电脑dns win10电脑修改dns的具体方法[多图]
  17. 姿态估计论文思路整理 -- Realtime Multi-Person 2D Pose Estimation using Part Affinity Fields
  18. OSChina 周六乱弹 —— 啊,谢谢好心的先生
  19. Shiro 第十七章 OAuth2集成
  20. ML - 贷款用户逾期情况分析5 - 特征工程2(特征选择)

热门文章

  1. Rinne Loves Data Structure
  2. 图论 ---- CF700 C. Break Up(Tarjan找桥+枚举+思维)
  3. python 多态_Python中的多态
  4. java请求慢_为什么重复的GET请求变慢了?
  5. 流网络的最小割问题c语言,「网络流24题」最小路径覆盖问题
  6. 【数学知识】三种方法求 [1,n] 中所有数欧拉函数(线性筛欧拉函数优化至 O(n) )
  7. 【树形DP】树的重心详解+多组例题详解
  8. poj2112(floyd+二分+二分图多重匹配)
  9. python for语句_Python循环语句
  10. linux sed 小数点,每天进步一点点——linux——sed