为什么我应该使用基于文档的数据库而不是关系型数据库?

212

为什么我应该使用像CouchDB这样的文档数据库而不是使用关系型数据库?有哪些典型的应用程序或领域在文档数据库比关系型数据库更合适?


或许面向文档的数据库在某些方面与“实体-属性-值”(EAV)数据库类似。 - ChrisW
9个回答

190

也许你不应该使用它 :-)

第二个最明显的答案是,如果你的数据不是关系型的,那么你应该使用文档数据库。这通常表现为没有简单的方法将数据描述为一组列。一个很好的例子是一个实际存储纸质文件的数据库,例如通过扫描办公邮件。数据是扫描的PDF文件,你有一些始终存在的元数据(扫描时间、扫描者、文档类型)以及存在许多可能的元数据字段(客户号码、供应商号码、订单号码、保留至、OCR全文等)。通常情况下,你事先不知道在未来两年内会添加哪些元数据字段。 对于这种类型的数据,像CouchDB这样的东西比关系型数据库更加好用。

我个人也喜欢事实上不需要任何CouchDB客户端库,除了一个HTTP客户端,这在几乎每种编程语言中都被包含。

也许最不明显的答案是:如果你使用关系型数据库没有痛苦,那就继续使用它。如果你总是不得不绕开关系型数据库才能完成工作,那么文档导向数据库可能值得一看。

要获取更详尽的列表,请查看Richard Jones的这篇文章


1
我在过去两年中从未见过任何数据库模式与我们最初开始的原始模式相似... 因此,即使一切相等(实际上并非如此...),您也应该始终使用无模式数据库=面向文档的数据库;我认为这是一个相当具有误导性的名称... - ՕլՁՅԿ
7
如果你无法将数据描述为一列列的形式,那么你如何编写针对该数据的智能查询呢? - Clay Smith

48

CouchDB文档(https://web.archive.org/web/20090122111651/http://couchdb.apache.org/docs/overview.html)中:

  • "一个文档数据库服务器,可通过RESTful JSON API访问。" 通常,关系型数据库不仅通过REST服务访问,还需要更复杂的SQL API。这些API(如JDBC、ODBC等)通常非常复杂。而REST则非常简单。

  • Ad-hoc并且无模式,具有平坦的地址空间。关系型数据库具有复杂的固定模式。您需要定义表格、列、索引、序列、视图和其他内容。Couch不需要这种水平的复杂、昂贵、脆弱的高级计划。

  • 分布式,具有鲁棒的增量复制和双向冲突检测和管理。一些SQL商业产品提供了类似功能。由于SQL API和固定的模式,这是复杂、困难和昂贵的。对于Couch而言,它似乎很简单且不需要花费太多。

  • 可查询和可索引,具有表格导向的报表引擎,使用JavaScript作为查询语言。这也是SQL和关系型数据库所使用的。没有什么新东西。

那么,为什么选择CouchDB呢?

  • REST比JDBC或ODBC更简单。
  • 无模式比模式更简单。
  • 以看似简单且不费太多成本的方式进行分布式。

14
虽然我很喜欢NoSQL数据库,但第一个说法(REST比JDBC更简单)非常值得怀疑。 - ՕլՁՅԿ
2
REST协议对我来说似乎相当简单,因为它只是HTTP:无状态、少量方法等等。也许JDBC在底层上很简单;仅仅基于有状态并不意味着它更简单。 - S.Lott
6
回答应更加“通用”而不是仅针对CouchDB吗? - Pacerier
1
“脆弱的高级规划”与什么相比呢?根据我的经验,另一种选择是没有规划,这会导致随意修改的意大利面式数据结构。 - Tejay Cardon

32

用于存储和提供其他服务器数据的愚蠢方法。

在过去几周中,我一直在使用一个生活流应用程序来轮询我的 feeds (delicious, flickr, github, twitter...),并将它们存储在couchdb中。couchdb的美妙之处在于它让我在没有额外开销的情况下保留原始数据的原始结构。我为每个文档添加了一个“class”字段,存储源服务器,并为每个源编写了一个javascript渲染类。

总体来说,当您的服务器与另一个服务器通信时,无模式存储是最好的选择,因为您无法控制模式。作为奖励,couchdb使用服务器和客户端的本地协议——JSON表示和HTTP REST传输。


为什么不直接将它们存储在一个文件中,或每个源的文件中呢? - j_random_hacker
6
因为CouchDB还可以使用map/reduce创建有趣的视图。例如,我可以基于数据源创建一个视图,或者计算每个源的总数。 - daonb
5
如果你正在使用数据且无法控制传入数据模式,那么“使用文档存储”是一个绝佳的观点。 - Joshua Robinson
1
这是我听到的第一个真正令人信服的关于NoSQL数据库价值的论点。 - Caleb McNevin

24

快速应用程序开发是首先想到的。

当我不断演变我的模式时,我经常感到维护MySQL/SQLite中的模式非常繁琐。虽然我还没有太多涉及CouchDB的经验,但我喜欢在RAD过程中如何简单地演变模式。

一个你可能不想使用非关系型数据库的情况是当你有很多多对多的关系;我还没有摆脱如何围绕这些关系创建好的MapReduce函数的困扰,特别是如果你需要在连接关系中有元数据。我不确定,但我认为CouchDB Map函数不能调用它们自己在数据库上的查询,因为那可能会导致无限循环。


2
很好的观点。文档(以及其他无模式)数据存储对于快速的早期开发非常有用。然而,出于同样的原因,它们对于强大的生产应用程序来说也是有问题的。 - Tejay Cardon

9

当您不需要将数据存储在具有每个记录均匀大小字段的表中时,请使用基于文档的数据库。相反,您需要将每个记录作为具有特定特征的文档进行存储。在任何时候都可以动态地向文档添加任意数量和长度的字段,无需首先“修改表”。基于文档的字段还可以包含多个数据。


3
这要看情况。
是的,这与用例有关。 是的,这也与开发者体验有关。 是的,输入数据的性质很重要(高度可预测、正交、合理化且易于标准化,或不太可能以任何有意义的方式进行标准化/组织)。 是的,一个记录/对象与另一个记录/对象的关系(如果有的话)很重要。 是的,你需要分析数据的方式很重要。 是的,所支持的应用程序的性质很重要(数据在应用程序中的使用方式)。
是的,如果一个记录/文档的结构(模式)必须快速更改,或者字段本身不能强制为每个记录/文档,则很重要。
是的,如果您有大量数据需要存储,并且想要减少检索时间,则很重要。规范化数据(许多单独的、不同的表中的数据)往往需要以某种方式组合在一起(连接、子查询等)才能返回有用的结果。通过只返回一些文档或集合(带有一些过滤),可以更快地返回相同的结果。
哦,是的,为了让新世界秩序感到被认可……那些将JavaScript或Python作为他们的第一种编程语言学习的人很高兴不再被SQL所负担。例如,MongoDB将数据存储为BSON,对于只关心获取他们想要的数据的人来说,这实际上看起来像JSON——没有模式,只需存储/获取数据并转到下一个事项。
坦白地说,您学习的第一种语言很重要。如果您先学习了SQL,则有一个地方可以放置每个东西,每个东西都在其位置上。你不介意定义/修改模式,因为它让你非常了解你的数据。实际上,有些人喜欢SQL,因为它给用户带来了控制感。他们不介意知道另一种领域特定的语言,因为它给用户带来了力量。由于SQL自70年代以来就存在,它基本上是老派商业做事的方式。
使用SQL RDBMS的成本包括计划和修改模式的时间(必要时进行分区)、计划表大小和可扩展性(集群)、学习与数据库交互并将记录转换为编程语言数据结构(ORM或其他)的时间。
然而,当涉及到分析数据和提出复杂问题时,SQL非常有效。如果你有超过简单存储和检索需求(带有轻微分析),那么SQL会让你远远领先于其他方法。
然而,对于应用程序的所有数据要求来说,规范化的SQL数据库作为一个整体不一定适合。应用程序(Web或其他)可能存在与业务的核心和中心无关的方面。
如果您想要一个经过验证的、符合ACID标准的交易(带有回滚)记录系统用于您的财务记录(付款、购买等……)——例如,如果您是银行——那么我会选择SQL,无论文档数据库有多好。然而,UI中的某些小部件甚至可能不涉及客户记录/业务交易。为什么要为此创建模式呢?
实际上,这是核心UI Web开发人员的观点。他们可以使用文档数据库来简化开发生活,但不是为了使您的业务交易满足ACID标准。随着经验的增加,他们将更加明白文档数据库的便利性只是一种“方便”。
我敢肯定,当我打字时,有人会说现在某个文档DB已经具有ACID兼容事务了,但它是否还具有SQL?最终,那些想要将文档DB用于所有事情的人将找到实现它的方法-这可能意味着(除其他事项外)集合和文档将有更多的限制,并开始变成模式的形式。
看吧,对于像REST和GraphQL API这样的东西,你永远不知道你可能从哪里获取数据。您无法预测或提前计划所有数据的形式。在这种情况下(比如与Amazon Web Services API进行交互),文档数据库是有意义的。您不想规范化那么多数据。你只需要访问、过滤它并执行基本操作以满足应用程序的需求。将这些数据转储到SQL数据库中可能是浪费时间。每次AWS使用新数据更新服务时,您可能需要更改代码和模式以适应它。啊!把它存储在集合和文档中!
上面的AWS API示例不涉及事务。如果您需要保留某些API信息,则无需使用大量表格。不幸的是,有些人试图使每个场景都适合这种用例,他们错了!
进一步说,考虑到可能从AWS API中摄取的数据量,将存储在集合和文档中的数据进行分片和聚集要简单得多,而与SQL数据库的分区和聚集相比要简单得多。如果您从事运营工作,那么文档数据库更容易管理,最终是如此。
因此,虽然我喜欢这里很多答案,但许多人似乎只是捍卫自己的阵营并/或仅在解释文档数据库可能比基于架构、正交、SQL数据库更合适的场景时稍微解释一下。
经验法则: 1. 如果对于您的业务操作和持续经营(CRUD、ACID、事务)至关重要,请使用SQL。 2. 如果只是为了处理大量数据以供应用程序和UI处理,请使用文档/NoSQL数据库。

我想补充一点,你还需要考虑到可能会受到的限制。比如,我在使用S3时达到了每秒最大读取次数,DynamoDB本地二级索引的最大记录大小等等。在选择某个服务之前,始终要检查一下限制情况——这可能不会影响你的决策,但还是值得了解一下。然后将其与最坏情况进行比较。我确实觉得有趣的是你指出很多人最终在NoSQL数据库中使用了模式(schemas)——我也见过同样的情况。它们非常适合高吞吐量的场景,但如果应用程序没有同时更新,模式更改可能会导致问题。 - ps2goat

2
为了进一步解释smdelfin所说的:灵活性。你可以以任何结构(非结构化等)存储数据,每个文档都可以完全不同。CouchDB特别有用,因为它具有“视图”索引,您可以过滤特定文档并在需要这些子集的数据库时查询该视图。
我认为文档数据库以JSON格式存储数据是最大的优势:这是JavaScript的本机格式。因此,JavaScript Web应用程序与CouchDB非常兼容。我最近制作了一个利用CouchDB的Web应用程序,它速度非常快,同时能够处理不断变化的数据结构。

2
文档型数据库比关系型数据库具有一个很大的优势,即不需要预先定义模式-在输入任何数据之前。如果您的数据不是关系型且不能存储在表中,而是一组图像或例如报纸文章,则应使用文档数据库。另一个优点是易于在Web开发中使用基于文档的数据库。要了解更深入的NoSQL数据库模型比较,请查看此来源:https://arxiv.org/ftp/arxiv/papers/1509/1509.08035.pdf

0
一个原因是为了在 JSON(或其他自我描述格式)文档上提供快速的全文搜索,这些文档可能没有相同的结构/模式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接