我错过了一些关于文档数据库的内容吗?

时间:2010-08-09 13:14:14

标签: nosql document-database

我一直在关注NoSql运动的兴起以及随之而来的mongodb,ravendb等文档数据库的普及。虽然我喜欢这些有很多相关的东西,但我觉得我并不理解一些重要的东西。

假设您正在实施商店应用程序,并且您希望在数据库产品中存储所有这些产品,这些产品都具有单一的唯一类别。在关系数据库中,这可以通过具有两个表,产品和类别表来完成,并且产品表将具有一个字段(可能称为“category_id”),该字段将引用具有正确类别条目的类别表中的行。这有几个好处,包括不重复数据。

这也意味着,如果你拼错了类别名称,例如,你可以更新类别表然后它是固定的,因为那是唯一存在价值的地方。

但是,在文档数据库中,这不是它的工作原理。你完全非规范化,意味着在“产品”文档中,你实际上会有一个保存实际类别字符串的值,导致大量重复数据,并且错误更难以纠正。更多地考虑这一点,是否也意味着运行诸如“给我所有具有此类别的产品”之类的查询会导致结果不具备完整性。

当然,解决这个问题的方法是在文档数据库中重新实现整个“category_id”事物,但是当我在思考中达到这一点时,我意识到我应该继续使用关系数据库而不是重新实现他们。

这让我相信我错过了关于文档数据库的一些关键点,这些关键点导致我走上了这条不正确的道路。所以我想把它放到堆栈溢出,我错过了什么?

4 个答案:

答案 0 :(得分:18)

  

你完全非规范化,意思是在“产品”文档中,你实际上会有一个保存实际类别字符串的值,导致大量重复数据[...]

正确,非规范化意味着存储其他数据。它还意味着更少的集合(SQL中的表),从而减少了数据之间的关系。每个单个文档都可以包含来自多个SQL表的信息。

现在,如果您的数据库分布在多个服务器上,则查询单个服务器而不是多个服务器的效率更高。使用文档数据库的非规范化结构,您更有可能只需要查询单个服务器以获取所需的所有数据。使用SQL数据库,您的相关数据可能会分布在多个服务器上,从而使查询效率非常低。

  

[...]并且错误更难以纠正。

也是如此。大多数NoSQL解决方案都不保证参考完整性等内容,这些内容对SQL数据库来说很常见。因此,您的应用程序负责维护数据之间的关系。但是,由于文档数据库中的关系量非常小,所以它并不像听起来那么难。

文档数据库的一个优点是架构。您可以随时自由定义文档的内容;您没有像使用SQL数据库那样绑定到一组预定义的表和列。

真实世界的例子

如果您在SQL数据库之上构建CMS,则要么为每个CMS内容类型都有一个单独的表,要么为具有通用列的单个表存储所有类型的内容。使用单独的表格,您将拥有很多表格。只需考虑每种内容类型的标签和评论等内容所需的所有连接表。使用单个通用表,您的应用程序负责正确管理所有数据。此外,数据库中的原始数据在CMS应用程序之外难以更新且无意义

使用文档数据库,您可以将每种类型的CMS内容存储在单个集合中,同时在每个文档中保持强定义的结构。您还可以在文档中存储所有标记和注释,使数据检索非常高效。这种效率和灵活性需要付出代价:您的应用程序更负责管理数据的完整性。另一方面,与SQL数据库相比,使用文档数据库扩展的价格要低得多。

建议

如您所见,SQL和NoSQL解决方案都有优点和缺点。作为大卫already pointed out,每种类型都有其用途。我建议您分析您的需求并创建两个数据模型,一个用于SQL解决方案,另一个用于文档数据库。然后选择最适合的解决方案,牢记可扩展性。

答案 1 :(得分:9)

我会说你忽略的第一件事(至少根据帖子的内容)是文档数据库并不是要取代关系数据库。事实上,您提供的示例在关系数据库中工作得非常好。它可能应该留在那里。文档数据库只是另一种以另一种方式完成任务的工具,它们并不适合于每项任务。

文档数据库是为了解决(以相反方式看待)问题,关系数据库不是解决每个问题的最佳方法。这两种设计都有它们的用途,它们本身都不比另一种好。

查看MongoDB网站上的用例:http://www.mongodb.org/display/DOCS/Use+Cases

答案 2 :(得分:4)

文档数据库在您启动时给人一种自由的感觉。您不再需要编写create table和alter table脚本。您只需在主“记录”中嵌入详细信息即可。

但过了一会儿,你意识到你被锁定在一个不同的方式。以您在存储数据时认为不需要的方式组合或聚合数据变得不那么容易。数据挖掘/商业智能(搜索未知)变得更加困难。

这意味着检查您的应用是否以正确的方式将数据存储在数据库中也更加困难。

例如,您有两个集合,每个集合大约有10000个'记录'。现在你想知道'table'A中哪些id不存在于'table'B中。

使用SQL琐碎,使用MongoDB会更加困难。

但我喜欢MongoDB !!

答案 3 :(得分:0)

例如,

OrientDB支持无模式,模式完整或混合模式。在某些情况下,您需要约束,验证等,但您需要灵活地添加字段而不触及架构。这是一种模式混合模式。

示例:

  

{     '@rid':10:3​​,     '@class':'客户',     '@ver':3,     '名字':'周杰伦',     'surname':'矿工',     '发明':['Amiga']   }

在此示例中,“name”和“surname”字段是强制性的(通过在模式中定义它们),但是仅为此文档创建了“发明”字段。您的所有应用都需要了解它,但您可以针对它执行查询:

  

SELECT FROM Customer WHERE发明了IS NOT NULL

它只返回带有“发明”字段的文档。