面向列的NoSQL如何与面向文档的不同?
我读过的三种NoSQL数据库是键值,列导向和面向文档。
键值非常简单 – 一个明码标价。
我已经将面向文档的数据库描述为键值,但是值可以是一个结构,就像一个JSON对象。 每个“文档”可以具有全部,部分或不具有与另一个相同的密钥。
面向列似乎非常像面向文档,因为你没有指定结构。
那么这两者之间有什么区别呢?为什么你会使用一个呢?
我专门研究了MongoDB和Cassandra。 我基本上需要一个dynamic结构,可以改变,但不会影响其他值。 同时,我需要能够search/过滤特定的键和运行报告。 对于CAP,AP对我来说是最重要的。 数据可以“最终”跨节点同步,只要数据没有冲突或丢失即可。 每个用户将获得自己的“表”。
在卡桑德拉(Cassandra),每一行(由一个关键字)包含一个或多个“列”。 列本身是键值对。 列名不需要预定义,即结构不固定。 一行中的列根据其键(名称)按sorting顺序存储。
在某些情况下,你可能在一行中有很大数量的列(例如充当索引来启用特定种类的查询)。 Cassandra可以有效地处理这样大的结构,并且可以检索特定范围的列。
还有一个更高层次的结构(不常用)称为超级列,其中一列包含嵌套(子)列。
你可以把整体结构看作是一个嵌套的散列表/字典,有2或3级的密钥。
普通列族:
row col col col ... val val val ...
超级柱子家族:
row supercol supercol ... (sub)col (sub)col ... (sub)col (sub)col ... val val ... val val ...
还有更高级别的结构 – 列族和密钥空间 – 可以用来划分或分组数据。
另见这个问题: Cassandra:什么是子列
或http://wiki.apache.org/cassandra/ArticlesAndPresentations中的数据build模链接;
Re:与面向文档的数据库比较 – 后者通常插入整个文档(通常是JSON),而在Cassandra中,可以对单个列或超级列进行处理,并分别进行更新,即以不同的粒度级别进行工作。 每个列都有自己的单独时间戳/版本(用于协调整个分布式集群的更新)。
Cassandra列值只是字节,但可以键入为ASCII,UTF8文本,数字,date等
当然,通过插入包含JSON的列,您可以将Cassandra用作原始文档存储,但是您不能获得真正的面向文档的存储的所有function。
主要区别在于文档存储(例如MongoDB和CouchDB)允许任意复杂的文档,即子文档中的子文档,文档列表等,而列存储(例如Cassandra和HBase)仅允许固定格式,例如严格的单层或两级字典。
在“插入”中,要使用rdbms这个词,基于文档的是更加一致和直截了当的。 请注意,与cassandra相比,您可以达到与法定人数概念的一致性,但这不适用于所有基于列的系统,并且会降低可用性。 在一次写入/读取往往很重的系统上,去MongoDB。 如果你总是打算读取对象的整个结构,也要考虑它。 一个基于文档的系统被devise为当你得到它时返回整个文档,并且在整行的返回部分不是很强。
像Cassandra这样的基于列的系统比“更新”中的文档更好。 您甚至可以在不读取包含该列的行的情况下更改列的值。 写入不需要在同一台服务器上完成,一行可能包含在多个服务器的多个文件中。 在巨大的快速发展的数据系统上,去Cassandra。 如果您打算每个密钥都有非常大的数据块,并且不需要在每个查询中加载所有的数据,那么也要考虑它。 在“select”中,Cassandra让你只加载你需要的列。
另外还要考虑Mongo DB是用C ++编写的,是第二个主要版本,而Cassandra需要在JVM上运行,它的第一个主要发行版本是从昨天开始才发布的(但是0.X发行版转大公司已经)。
另一方面,Cassandra的devise部分基于Amazon Dynamo,其核心是构build高可用性解决scheme,但这与基于列的格式没有任何关系。 MongoDB也可以扩展,但不像Cassandra那样优雅。