我读过的三种类型的NoSQL数据库是键值,面向列和面向文档。
键值非常简单 - 具有普通值的键。
我看到面向文档的数据库被描述为键值,但值可以是结构,就像JSON对象一样。每个“文档”可以包含全部,一些或没有相同的键。
面向列的方式似乎与文档导向非常相似,因为您没有指定结构。
那么这两者之间有什么区别,为什么你会使用另一个呢?
我特别关注MongoDB和Cassandra。我基本上需要一个可以改变的动态结构,但不会影响其他值。同时,我需要能够搜索/过滤特定密钥并运行报告。有了CAP,AP对我来说是最重要的。只要没有冲突或数据丢失,数据就可以“最终”跨节点同步。每个用户都会得到他们自己的“桌子”。
答案 0 :(得分:42)
主要区别在于文档存储(例如MongoDB和CouchDB)允许任意复杂的文档,即子文档中的子文档,带有文档的列表等,而列存储(例如Cassandra和HBase)仅允许固定格式,例如,严格的一级或两级词典。
答案 1 :(得分:32)
在Cassandra中,每一行(由一个键寻址)包含一个或多个“列”。列本身就是键值对。不需要预定义列名,即结构不固定。连续的列根据其键(名称)按排序顺序存储。
在某些情况下,您可能会在一行中包含非常多的列(例如,充当索引以启用特定类型的查询)。 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: What is a subcolumn
来自http://wiki.apache.org/cassandra/ArticlesAndPresentations
的数据建模链接Re:与面向文档的数据库进行比较 - 后者通常插入整个文档(通常是JSON),而在Cassandra中,您可以寻址单个列或超级列,并单独更新它们,即它们以不同的粒度级别工作。每列都有自己独立的时间戳/版本(用于协调分布式群集中的更新)。
Cassandra列值只是字节,但可以输入为ASCII,UTF8文本,数字,日期等。
当然,您可以通过插入包含JSON的列来使用Cassandra作为原始文档存储 - 但是您不会获得真正面向文档的存储的所有功能。
答案 2 :(得分:23)
在“插入”中,要使用rdbms字样,基于文档的更加一致和直接。请注意,与cassandra相比,您可以实现与仲裁概念的一致性,但这不适用于所有基于列的系统,并且会降低可用性。在一次写入/读取常常很重的系统上,转到MongoDB。如果你总是计划阅读对象的整个结构,也要考虑它。基于文档的系统设计用于在获得整个文档时返回整个文档,并且在返回整行的部分时不是很强。
像Cassandra这样的基于列的系统比“更新”中的基于文档的方式更好。您可以更改列的值,甚至不读取包含它的行。写操作实际上不需要在同一台服务器上完成,一行可能包含在多个服务器的多个文件中。在巨大的快速发展的数据系统上,去找Cassandra。如果您计划每个密钥拥有非常大的数据块,并且不需要在每个查询中加载所有数据,请考虑它。在“选择”中,Cassandra允许您只加载所需的列。
还要考虑Mongo DB是用C ++编写的,并且是第二个主要版本,而Cassandra需要在JVM上运行,并且它的第一个主要版本仅在昨天发布候选版本(但0.X版本已经转向已经在主要公司的制作中。)
另一方面,Cassandra的设计部分基于Amazon Dynamo,它的核心是高可用性解决方案,但这与基于列的格式没有任何关系。 MongoDB也可以扩展,但不像Cassandra那样优雅。
答案 3 :(得分:0)
我要说的主要区别是,每种DB类型在物理上存储数据的方式。
对于列类型,数据按列存储,这可以对特定列进行有效的聚合操作/查询。
对于文档类型,整个文档在逻辑上存储在一个位置,并且通常作为一个整体进行检索(“列” /“字段”上不可能进行有效的聚合)。
令人困惑的一点是,宽列“行”可以轻松地表示为文档,但是,正如前面提到的,它们以不同的方式存储并针对不同的目的进行了优化。