分库分表的孪生兄弟--不一样的分区篇(下)

这是更新的间隔时间比较长。回顾一下上一篇文章的内容。

数据库为什么要有分区?引《孙子兵法》的第五篇-《兵势篇》孙子曰:凡治众如治寡,分数是也。斗众如斗寡,形名是也。说人话:凡是管理很大的数据库表就和管理小的数据库表一样,把它分区就好了;发挥好每一个分区的功能就和发挥好其中一个分区的功能一样,他们能有一个统一的表名,可以使用统一的SQL语句来调度就好了。上面这段话,从分号隔开,可以分成上下两句。“伟大”是在于前半句还是后半句呢?显然是后半句。为啥?你把人分了容易,但是你要把茫茫多的分开的人,指挥得像一个人一样,这件事情就伟大了。
上半篇主要写了前半句,什么情况下去分库分表。这一篇将主要写的概念是后半部分,斗众如斗寡,形名是也。
斗众如斗寡,这句话讲起来简单,实现起来可不是那么简单。在主流的DBMS里面,不同的分区意味着不同的对象(如ORACLE中,不同的SEGMENT,DB中不同的文件)。不夸张的说,很多数据库中间件产品,在反复纠缠、实现的内容,其实本身就是主流DBMS在分区时要处理掉的技术关口。比如有:跨库的SQL重写,一个运行在分布式场景的SQL,需要被中间件重写成多个SQL,丢到多个库去执行。尤其是,跨库的连结、聚合(包括Max,Min,Sum,Count)。其实在多分区的时候,一样存在这样的问题。 如果说这个问题,不太容易被开发者所关注到。再举一个例子:全局/本地索引。
在DBMS中,全局索引通常是要在设计上所回避的。一般数据表一旦分区,意味着数据量比较大。例如最常见的B树索引,全局索引意味索引层次多,查询速度慢。但是当无论如何,我在查询时,无法送入分区KEY时,全局索引总归还是最后的选择。而在分布式场景里,没有分库KEY就会非常尴尬,要么查不了,要么就要遍历所有的库,这个代价几乎就是不可接受的。
分区和分库面临的很多问题都存在着巨大的相似之处,开发者总是会重视分库所面临问题和困难,然而普遍会轻视分区可能带来的副作用。我常常被质问,数据多了,为什么不加分区!?并发有冲突,为什么不加分区!?程序速度慢了,为什么不加分区!?PS:这一系列的质问,同样适用于为什么不加索引系列。
这种轻视源自于,主流DBMS系统对分区功能的很好的支撑。作为DBA,比较害怕的是有人懂一点数据库,且特别自信的站在他自己立场来和我讨论。有一些开发者传递给我一个理念,分区多比分区少要好。只要用了分区,就能更快,至少不可能更差!开发者在说起这些的时候,非常的自信。其实,在我看来分区设计和查询优化是密切相关的。分区设计一定是与特定的查询场景匹配,才能达到好的结果。比如之前提到的没有分区列送入的查询需要逐个遍历每个分区,再比如说HASH分区后的范围查找。Oracle中索引的HASH分区,在大规模的高并发插入的数据库表上应用十分常见,因为这种场景非常容易产生冲突事件 ,使用HASH分区之后,可以极大的缓解。然而这也挖下了一个坑,那就是这个索引上的范围查找就变得不那么理想。
由此推论,分区上可以能遇到的大坑,其实在分库的场景同样使用。比如说,做了分库,却发现交易的业务场景拿不到SHARDING KEY。采用了HASH的算法,算SHARDING KEY,又突然发现,有个交易,要范围查SHARDING KEY,以至于可能要去各个库兜一圈。分区面对的坑,可以说在分库场景下,是急剧放大了。所以,不可以随意滥用分区,更加不可以随便乱分库。
反过来讲,我为何在开篇说分区十分伟大,尤其是Oracle。在你违背了种种优化原则之后,做了npi,做了跨分区的join等等,尽管有性能上的损失,无论如何,数据库都帮你把那些复杂的工作给完成了。当你的需求不是实时响应时,这些奇奇怪怪的跨分区要解决的问题,Rdbms都还是对你透明的把这些工作给你做完了。这怎么能不说它是伟大的呢?我想那些开发分布式数据库中间件的人,最能赞同。
最后写到这里,作为一个DBA,我特别希望给程序开发者灌输一个理念,那就是这世界上一定没有一个完美的优化方案。你要一个表,又能高并发插入,又能做各种各样高效的查询,一会范围,一会模糊。我只想说,这是不可能的。所有优化方案都是以牺牲某一种性能来换另一种性能。而DBA的职责,就是搞清楚业务需要什么,不需要什么。牺牲掉不需要的功能,换取需要的功能,甚至于牺牲不常用的功能,换取优异的常用功能,其实就是完美的方案,分区也不例外。
在本文的最后,我想留一个我一直困惑的问题。在我看了无数篇分库分表放在一起的文章和帖子之后,我开始怀疑人生了。我很想知道,无论在什么RDBMS中,是不是真的有,应该采用分表,而不适合采用分区的场景呢?这个场景用分表解决了什么问题,是不可以依靠分区来解决的,欢迎留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值