为什么新的分布式数据库又开始支持关系模型了?
长久以来关系数据库的最明显的痛点不外乎以下两点1.scale2.容错不好,分布式事务基本不可用。为了弥补以上问题,几乎现在成规模的互联网公司都有自己的一套DAL(MySQLSharding/Proxy),可这基本上是一个马后炮的方案。还有一个现象就是互联网公司对关系数据库的使用方式越来越像一个KV系统了(基本没有复杂查询)那么成熟nosql(HBaseCassandraMongo)解决了哪些问题?scale大部分nosql系统都能够非常好的解决这一类问题,集群规模上千台是没有任何压力的。这类系统在设计上主要有2大类吧(有中心节点,无中心节点)。HBase源于googlebigtable相当于在hdfs上面做了一个分布式索引层。扩展不是问题。多副本能够保证数据可靠。那么再回过头来看看数据库的本质的东西数据库与文件系统最本质的区别就是有Transaction的能力。在分布式系统中做到这个很不容易(2pc,3pcraft,paxos)。在一个SQL表现力很强(要不分也不会有Hive,Impala)。基本上朴素的数据分析或者说规律性的分析用SQL完全能够搞定。所以关系模型如何能够在分布式系统下还能够保持这些优秀的特性NewSQL最好选择啊!
最好的数据库,常用的功能都应该提供,但要留给用户自己去选择。比如不需要关系的,就不勾选关系功能,这样数据库的性能会更高。现在市面的数据库,性能高的缺乏功能,功能多的又无法手动关闭不需要的功从而导致很多没必要的性能损失。
1.分布式数据库的需求,率先是由互联网公司碰到的,这些公司用传统的关系型数据库做业务很痛苦,不得不自造轮子。而由于自身的业务并不复杂,所以重点在解决分布式的问题(通过分布式技术降低硬件要求),而不用考虑复杂计算的问题(即支持sql或者100%兼容SQL标准语法)。BigTable、HBase、Redis等,无一不是这种情况。2.欠下的债总是要还的,互联网在跑马圈地之后,逐渐侵入传统领域,这时候发现没有关系演算,或者说没有SQL这种描述能力强悍的语言不行,业务开发会很麻烦;还有比如需要事务的支持。正如轮子哥所说的:“关系是用来保持事务和并发的正确性的,显然大家又重新意识到,这种事情让程序员写C++来保证是多么的不靠谱。”3.于是不得不回到更大的范围来考虑数据库的问题,所以从才出现了各种NewSQL,比如OceanBase,TiDB等。
这个问题很有意思,要分析好这个问题,可能要从过去的历史谈起。把时间往前推十多年,在2005年左右,我们可以看到在互联网领域,面对爆炸性增长的数据和请求量,以及互联网公司低IT成本的诉求,传统的关系型数据库逐渐力不从心了。总的来说,有两个主要的问题,一个是缺乏好的横向扩展能力,一个处理单个请求的延时高。为什么有这两个问题?要回答好这个问题,我们需要把时间再往前推几十年,看看关系型数据库,是怎么变成2005年那个样子的。众所周知,关系型的数据库,首先是跟网状/层次模型的数据库干了一仗,才奠定其江湖地位的。最终的结果是关系型数据库成为结构化数据存储的标配,而其他类型的数据库则逐渐消失。
我们通常所说的“关系数据库管理系统”是指具备以下两个核心功能的系统:以SQL作为数据定义/操作语言的关系型数据管理;数据的访问和操作符合事务语义。前者是数据模型的抽象。关系模型是在应用中数据建模的便利性和系统实现和性能优化之间(长期以来被认为能够达到合理平衡)的折中。在建模便利性/灵活性上,它不如OO建模;在性能优化实现上,它可能不如被深度定制/优化的很多系统。但在上世纪70年代末,关于关系数据库是否能达到层次/网状数据模型数据库的性能的争论,以及上世纪80年代末/90年代初,关于是否应该实现完全的面向对象数据模型的数据库管理系统的争论,这两场争论过后,我们现在看到的关系模型加上一些面向对象特性的数据模型抽象就基本成型了。MichaelStonebraker把这种系统叫做ORDBMS[1]。PostgreSQL是ORDBMS的代表。后者是数据操作的抽象。事务一致性有不同级别[2],ANSI/ISOSQL对隔离级别有定义,不同厂商的系统的实现不同,有的还实现了其他隔离级别。无论是关系模型还是事务,都可以通过SQL来定义和操作。所以,很多时候SQL就被当作关系数据库管理系统的代名词。BigTable/HBase刚出现时,既没有关系模型支持(甚至都没有数据模型支持)也没有事务实现。所以后来这批系统(还有Cassandra,甚至包括Hadoop/MapReduce等)被称为NoSQL,就是“没有SQL的数据管理系统”。说它们“比关系数据库多了一层”是不合适的。
一旗帜鲜明地先说结论:之所以新的分布式数据库又开始支持关系模型了,是因为大部分程序员的数据库水平太糟糕。二论证之前惯例先吐个小槽。咱们就不吐槽题主的问题描述本身是不是就已经论证了我的观点,比如啥“良好的查询语言”是不是等于SQL等于关系模型,又比如“比关系数据库多了一层”是什么奇怪的说话。我还是来讲两个真实的小故事吧。大概4、5年前,大家还在老老实实地用RDBMS实现业务数据库,一段时间过去发现查询变得很慢,大家纷纷议论:要不要换成NoSQL啊?然后我被派去做帮助做数据库优化,然后加了几个索引,把查询的时间从30多秒优化到了30多毫秒。大概4、5个月前,大家已经开始快快乐乐地在新业务的数据库上用上NoSQL了,结果发现查询也开始变得很慢,大家纷纷议论:要不要用文档数据库来加个索引啊?然后我又被派来做NoSQL优化了,改了些partitionkey,重新定义了一些rowkey,拆了几个entity,然后查询时间从20多秒变成了20多毫秒。三要回答为什么新的分布式数据库又开始支持关系模型了,需要先搞明白两件事情:数据库解决了什么问题关系模型解决了什么问题数据库说得复杂特别复杂,但说得简单,它就解决了两个问题:数据怎么存放和数据怎么查询。而且这两个问题互相关联。举个程序员都能明白的例子:如果你把数据存成了数组,那搜索查询就只能是O(n)的效率了,如果你存成了二叉树,那么查询效率就变成了O(logn)。业务查询可不像搜索一个key值这么简单,常常复杂得要死,本来查询就很难写了,现在还得考虑数据物理存放方式来决定怎么执行查询更高效,这不是要逼死人嘛?所以早期的数据库开发人员苦啊,什么层级数据库、网状数据库写完查询都得自己定义accesspath啊。然后就有了关系模型。关系模型彻底改变了数据库程序员的生活:不用管数据怎么存了,你只要用SQL写好查询,然后查询优化器会帮你把面向业务的查询逻辑转换成可以高效在数据的物理结构上执行的物理查询。这简直就像一下从汇编时代跨越到了高级语言的时代啊。早期的数据库还需要大家自己思考怎么建索引,相当于告诉查询优化器哪些列是在查询中有用,后来数据库已经可以自动提示你该加什么索引了,大部分程序员终于可以欢乐地彻底扔掉数据库存储引擎的知识了。当然仍然有一小挫掌握了超能力的人,是可以手写执行计划,用PlanGuide强制执行的,他们说:查询优化器是什么?可以吃吗?若干年后他们拯救了世界也打开了黑暗的大门(大误...四好日子一直持续到数据库负载大到不得不开始走向分布为止。分布式最大的问题是网络延迟问题,而网络延迟是物理问题,没这么容易解决。跨机事务做不了啊,查询优化器再牛逼也优化不了跨网络的join啊。但业务还是得做啊,于是解决方案只有一个了:回到手工根据查询来决定数据物理分布(这样可以最大程度上避免跨网络的join),手工决定查询的物理执行计划,手工保证事务性的老路。既然都已经全手工了,那还要原来的RDBMS干嘛,于是NoSQL产品诞生了。搭配一些会手写执行计划手写事务的超能力者使用,战斗力简直有105这么高。大家很快就忘记了NoSQL其实是一个对现实妥协的产物,只有搭配一些精通数据存储引擎知识的人才能用好。推广开来之后,广大吃瓜群众表示NoSQL一点也不好用啊,自己要管的东西太多啦,我怎么知道要怎么设计数据的物理分布啊,瞎设计一下查询起来就效率感人了啊,最终一致又是一个什么鬼啦,想象一下讨论怎么严格保证一个“改动了3个entity且有不少if-else分支的方法”的最终一致性,感觉结论必然只有“呵呵”啊。于是为了让广大吃瓜群众用得开心,NoSQL的开发者不得不又开始走上了关系模型的老路。
比如汇编语言和高级语言,哪个表达力更强,哪个灵活度更高应该很明显。SQL的表达力是毋庸置疑,都(差不多?)是图灵完备的语言了,你说强不强,用KV的API写个正确的多表JOIN试试?。。。。而且最关键是,这个是事实标准啊。。。多少程序员是写完helloworld以后,就开始学SQL的。另外,我们发现关系模型其实是可以和分布式很好结合的,并非水火不容,而且关系模型本身并没有限定实现方式,只不过过去的RDBMS都是在单机上实现,很多Pattern并没有在分布式场景中有goodpractice,特别是OLTP,所以大家可能就会觉得这个没法做。其实还是能的,就是比较复杂,不过我相信我们团队能handle这个复杂度。另外很重要的一个就是轮子哥说到的事务,其实隔离级别和跨行事务是个好东西,能用更少的代码写出正确的程序,这个交给程序员写基本就呵呵了,只不过在分布式场景下需要牺牲点什么。本身MVCC并不是太难做,其实牺牲掉的是一定的延迟(分布式事务基本只有一种搞法:2PC)....不过呢,一旦想开了,这也不是什么大事,反正Multi-Paxos或者Raft这样的复制协议总是要有延迟的,2PC带来的contentioncost相比复制其实也不算太多。而且延迟问题也可以通过缓存和灵活降低隔离级别等方法搞定。
回答请先登录