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