NoSQL生态系统——类似Bigtable列存储,或者Dynamo的key存储(kv存储如BDB,结构化存储如redis,文档存储如mongoDB)
摘自:http://www.ituring.com.cn/article/4002#
NoSQL系统的数据操作接口应该是非SQL类型的。但在NoSQL社区,NoSQL被赋予了更具有包容性的含义,其意为Not Only SQL,即NoSQL提供了一种与传统关系型数据库不太一样的存储模式,这为开发者提供了在关系型数据库之外的另一种选择。
在关联型的数据模型中,在现实世界中的不同类型的个体被存储在不同的表里。比如有一个专门存员工的员工表,有一个专门存部门的部门表。简单的查询操作,比如查询符合某个条件的所有行(例:employeeid = 3, 或者 salary > $20000)。更复杂一些的任务会让数据库做一些额外的工作,比如跨表的联合查询(例:查出3号员的部门名称是什么)。一些复杂的查询,比如统计操作(例:算出所有员工的平均工资),甚至可能会导致全表扫描。
表结构的定义规定了表中每一行数据的存储内容。如果你的数据结构化并没有那么强,或者对每一行数据的要求比较灵活,那可能关联型的数据模型就太过严格了。
NoSQL运动受到了很多相关研究论文的启示,这所有论文中,最核心的有两个。 Google的BigTable[CDG+06]提出了一种很有趣的数据模型,它将各列数据进行排序存储。数据值按范围分布在多台机器,数据更新操作有严格的一致性保证。 Amazon的Dynamo[DHJ+07]使用的是另外一种分布式模型。Dynamo的模型更简单,它将数据按key进行hash存储。其数据分片模型有比较强的容灾性,因此它实现的是相对松散的弱一致性:最终一致性。 接下来我们会深入介绍这些设计思想,而实际上在现实中这些思想经常是混搭使用的。比如像HBase及其它一些NoSQL系统他们在设计上更接受BigTable的模型,而像Voldemort 系统它就和Dynamo更像。同时还有像Cassandra这种两种特性都具备的实现(它的数据模型和BigTable类似,分片策略和一致性机制和Dynamo类似)。
NoSQL系统舍弃了一些SQL标准中的功能,取而代之的是一些简单灵活的功能。NoSQL 的构建思想就是尽量简化数据操作,尽量让操作的执行效率可预估。在很多NoSQL系统里,复杂的操作都是留给应用层来做的,这样的结果就是我们对数据层进行的操作得到简化,让操作效率可预知。 NoSQL系统不仅舍弃了很多关系数据库中的操作。它还可能不具备关系数据库以下的一些特性:比如通常银行系统中要求的事务保证,一致性保证以及数据可靠性的保证等。事务机制提供了在执行多个命令时的all-or-nothing保证。一致性保证了如果一个数据更新后,那么在其之后的操作中都能看到这个更新。可靠性保证如果一个数据被更新,它就会被写到持久化的存储设备上(比如说磁盘),并且保证在数据库崩溃后数据可恢复。 通过放宽对上述几点特性的要求,NoSQL系统可以为一些非银行类的业务提供以性能换稳定的策略。而同时,对这几点要求的放宽,又使得NoSQL系统能够轻松的实现分片策略,将远远超出单机容量的大量数据分布在多台机器上的。
数据库的数据模型指的是数据在数据库中的组织方式,数据库的操作模型指的是存取这些数据的方式。通常数据模型包括关系模型、键值模型以及各种图结构模型。操作语言可能包括SQL、键值查询及MapReduce等。
13.2.1 基于key值存储的NoSQL数据模型
Key-Value 存储
Key-Value存储可以说是最简单的NoSQL存储。每个key值对应一个任意的数据值。对NoSQL 系统来说,这个任意的数据值是什么,它并不关心。比如在员工信念数据库里,exployee:30 这个key对应的可能就是一段包含员工所有信息的二进制数据。这个二进制的格式可能是Protocol Buffer、Thrift或者Avro都无所谓。 如果你使用上面说的Key-Value存储来保存你的结构化数据,那么你就得在应用层来处理具体的数据结构:单纯的Key-Value存储是不提供针对数据中特定的某个属性值来进行操作。通常它只提供像set、get和delete这样的操作。以Dynamo为原型的Voldemort数据库,就只提供了分布式的Key-Value存储功能。BDB 是一个提供Key-Value操作的持久化数据存储引擎。
Key - 结构化数据 存储
Key - 结构化数据存储,其典型代表是Redis,Redis将Key-Value存储的Value变成了结构化的数据类型。Value的类型包括数字、字符串、列表、集合以及有序集合。除了set/get/delete 操作以为,Redis还提供了很多针对以上数据类型的特殊操作,比如针对数字可以执行增、减操作,对list可以执行 push/pop 操作,而这些对特定数据类型的特定操作并没有对性能造成多大的影响。通过提供这种针对单个Value进行的特定类型的操作,Redis可以说实现了功能与性能的平衡。
Key - 文档 存储
Key - 文档存储的代表有CouchDB、MongoDB和Riak。这种存储方式下Key-Value的Value是结构化的文档,通常这些文档是被转换成JSON或者类似于JSON的结构进行存储。文档可以存储列表,键值对以及层次结构复杂的文档。 MongoDB 将Key按业务分到各个collection里,这样以collection作为命名空间,员工信息和部门信息的Key就被隔开了。CouchDB和Riak把类型跟踪这种事留给了开发者去完成。文档型存储的灵活性和复杂性是一把双刃剑:一方面,开发者可以任意组织文档的结构,另一方面,应用层的查询需求会变得比较复杂。
BigTable 的列簇式存储
HBase和Cassandra的数据模型都借鉴自Google 的BigTable。这种数据模型的特点是列式存储,每一行数据的各项被存储在不同的列中(这些列的集合称作列簇)。而每一列中每一个数据都包含一个时间戳属性,这样列中的同一个数据项的多个版本都能保存下来。 列式存储可以理解成这样,将行ID、列簇号,列号以及时间戳一起,组成一个Key,然后将Value按Key的顺序进行存储。Key值的结构化使这种数据结构能够实现一些特别的功能。最常用的就是将一个数据的多个版本存成时间戳不同的几个值,这样就能很方便的保存历史数据。这种结构也能天然地进行高效的松散列数据(在很多行中并没有某列的数据)存储。当然,另一方面,对于那些很少有某一行有NULL值的列,由于每一个数据必须包含列标识,这又会造成空间的浪费。 这些NoSQL系统对BigTable数据模型的实现多少有些差别,这其中以Cassandra进行的变更最为显著。Cassandra引入了超级列(supercolumn)的概念,通过将列组织到相应的超级列中,可以在更高层级上进行数据的组织,索引等。这一做法也取代了locality groups的概念(这一概念的实现可以让相关的几个行的数据存储在一起,以提高存取性能)。
13.2.2 图结构存储
图结构存储是NoSQL的另一种存储实现。图结构存储的一个指导思想是:数据并非对等的,关系型的存储或者键值对的存储,可能都不是最好的存储方式。图结构是计算机科学的基础结构之一,Neo4j和HyperGraphDB是当前最流行的图结构数据库。
未完待续!