这里将要想大家介绍四种NoSQL数据库的类型。
目前对于非关系型数据库主要有四种数据存储类型:键值对存储(key-value),文档存储(document store),基于列的数据库(column-oriented),还有就是图形数据库(graph database)。每一种都会解决相应的问题,这些问题是关系型数据库所不能解决的。而在实际应用中都会将这几种情况结合起来实现相应的功能。例如:OrientDB就是一种多类型的数据库,它整合了NoSQL的几种存储类型。OrientDB是一个图形数据库其每个节点都是一个文本。
在开始介绍NoSQL数据库之前,我们先来回顾一下关系型数据库,这样我们可以对非关系数据库和关系型数据库做一个深入的比较。在数据建模上面,很多方法都是有可能被使用的。关系型数据库会严格的按照标准化去建模(也就是常说的第一范式、第二范式、第三范式等等):确保每一条数据都只被存储一次。标准化是其结构设置的规范。例如:如果你想存储一个人的信息和这个人的爱好这样的数据,你可以创建两个表:一个用来存储这个人的信息,另一个表用来存储这个人的爱好。正如你在图一中看到的,你必须有一张额外的映射表,这张表将人的信息表和爱好表建立其对应的关系。这是因为他们的关系是多对多的关系,一个人可以有多个爱好,并且多个人可能会有相同的爱好。
图一
一个完整的关系型数据库会由很多的实体表和关系映射表构成,现在你已经有了和NoSQL数据库进行比较的东西了,下面让我们看看这些不同的存储类型。
基于列的数据库(column-oriented)
传统的关系型数据库时基于行(row-oriented)的,每一行都带有一个行id并且行中的每一个字段都存储在一张表中。假如说上面的例子中没有单独用一张表来存储人的爱好,我们仅用一张表来存储个人信息和爱好,如图二所示。这里你就需要注意了,这种请款下你已经有一点违反关系型数据库严格遵循的标准化了,因为爱好是有重复的。如果爱好是描述一个人很好的一条额外信息但是对你的用例没有什么重要性,那你可以将其列在Hobbies这一列中,这是可以接受的一种方法。但是如果这条信息对你根本不重要,那这些数据还有没有必要存呢?
图二
在基于行的数据库中进行查找的时候,每次都会对每一行进行遍历,不管某一列数据是否是你需要的都会进行遍历。假如你只需要生日是九月的人的数据,基于行的数据库会对这张表从上到下从左至右遍历一遍,正像你在图三中看到的那样,最后再返回你需要的那些数据。
图三
对特定列的数据进行索引能有效的提高查找速度,但是索引每一列同样会带来额外的负载,并且数据库同样也是会遍历所有的列来取得要查找的数据。
基于列的数据库会将每一列分开单独存放,当查找一个数量较小的列的时候其查找速度是很快的。其结构如图四所示
图四
这种设计看起来很像基于行的数据库在每一列上都加了索引一样。数据库索引这种数据结构以牺牲存储空间和更多的写文件(索引更新)为代价使查找速度得到提升。索引是将行号映射到数据上,而基于列数据库是将数据映射到行号上面,这样的方式用于计算是很简单的。例如上面的例子,查找有多少人的爱好包含archery(箭术)是很容易计算出来的。除此之外将每一列单独存放可以优化压缩因为每张表中只存一类数据。
说了这么多,那应该在什么时候使用基于行的数据库,在什么时候使用基于列的数据库呢?在基于列的数据库中要想增加一列新的数据是很容易的,因为现有的那些列是不会受新增列的影响的。但是要想增加一整条记录就需要适应所有的表,防止各个表的数据之间对应关系出现错误。因此这使得基于行的数据库在事务处理的时候要优胜于基于列的数据库,因为它很好的实现了数据的实时更新。
基于列的数据库的优势在于分析数据和对数据形成一个报告方面,例如对值求和、计算整条记录等。基于行的数据库经常被应用于实际交易中(例如销售业务)。夜间批处理作业就可以使基于列数据库更新,并且还支持快速查找还有使用MapReduce技术聚合数据形成报告。现在使用基于列的数据库存储数据的有Apache HBase,Facebook’s Cassandra,Hypertable和grandfather of wide-column stores,Google BigTable。
键值对存储(Key-Value Stores)
键值对的存储方式在NoSQL数据库中是最简单的一种,其结构就像其名字所示,是一个key-value的集合。如图五所示的那样。这种方式在NoSQL数据库类型中是最可扩展的一种类型,并且可以存储大量的数据。
图五
键值对中存储的数据的类型是不受限制的,可以是一个字符串,也可以是一个数字,甚至是由一系列的键值对封装成的对象等。图六向我们展示了一个比较复杂的键值对结构。使用价值对存储的数据库有Redis,Voldemort,Riak,和Amazon’s Dynamo。
图六
文档存储(Document Stores)
文档存储是基于键值对存储的,其结构较之于键值对存储更为复杂,可以说在键值对的基础上更深入了一步。文档存储是假定一个特定文档的结构可以使用一种特定的模式来说明,它的出现较之于其他的NoSQL数据库类型来说是最自然的,因为设计这种方式的最初的目的就是用来存储日常文档的,并且这种方式支持对于那些通常已经聚合的数据进行复杂的查询和计算。使用关系型数据库存储数据的方式在标准化的角度看是很有意义的:每条数据只被存储一次并且通过外键来进行联系。文档存储不会去关心那些所谓的标准化,只要数据在该结构下是有意义的就可以。所以说关系型数据库不能很好的适应特定企业的案例,只能用来做那些比较通用的案例。
例如:报纸和杂志包含有文章,如果想在关系型数据库中存储这些文章,首先你需要将这些文章给拆分开来,文章的内容在一个表中,文章的作者以及关于作者的信息要存在另一张表中,对于发布在网络上的文章的评论也需要额外的一张表来存储。正如图七所展示的那样,报纸上的一篇文章可以被存储为一个实例,这样在处理那些总是被查看的数据时可以减少查找的时间。使用文档存储的NoSQL数据库包含MongoDB和CouchDB。
图七
图形数据库(Graph Database)
现在剩下的是最后一个NoSQL数据库存储类型,也是最复杂的一个,主要使用一种高效的方式来存储各个实体之间的关系。当数据之间是紧密联系的,例如社会关系、科学论文的引文抑或是资本资产定价模型等等,使用图形数据库时最好的选择。图形或者网络数据有两部分组成:
Node-:实体本身,在一个社会关系中可以认为是一个人。
Edge-:实体之间的关系。这个关系可以用一条线来表示,这条线有它自己的属性。这条线可以有方向,箭头可以表明谁是谁的上级。
如果给予足够的关系和实体类型,图形会变得非常的复杂,其发杂程度简直难以置信。图八已经展示了仅有有限几个实体的复杂图形。像Neo4j图形数据库声称支持ACID,然而文档存储数据库和键值对数据库坚持BASE。
图八
非关系型数据库的潜力是无限的,当今世界关系正变得越来越紧密,图形存储类型很可能会在地理上胜过其他的存储类型数据库,包括现在仍然占绝对优势的关系型数据库。当今最流行的数据库的排名和他们是如何发展的在http://db-engines.com/en/ranking中都可以找到。
图九
图九列出了在九条记录中,关系型数据库在写这本书的时候在前15中仍然占主导地位。并且随着NewSQL的出现,我们还没有重新计算排名。Neo4j——当下最流行的图形存储数据库,在写本书的时候可以发现其处在23名的位置上,而Titan在53的位置上。