Nosql 我是否遗漏了有关文档数据库的内容?

Nosql 我是否遗漏了有关文档数据库的内容?,nosql,document-database,Nosql,Document Database,我一直在关注NoSql运动的兴起以及mongodb、ravendb等文档数据库的普及。虽然我喜欢这些东西,但我觉得我没有理解一些重要的东西 假设您正在实现一个存储应用程序,并且希望存储在数据库产品中,所有这些产品都有一个唯一的类别。在关系数据库中,这将通过有两个表来实现,一个产品表和一个类别表,产品表将有一个字段(可能称为“category_id”),该字段将引用类别表中包含正确类别条目的行。这有几个好处,包括不重复数据 这还意味着,例如,如果拼错了类别名称,则可以更新类别表,然后将其修复,因为

我一直在关注NoSql运动的兴起以及mongodb、ravendb等文档数据库的普及。虽然我喜欢这些东西,但我觉得我没有理解一些重要的东西

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

这还意味着,例如,如果拼错了类别名称,则可以更新类别表,然后将其修复,因为该值是唯一存在的位置

然而,在文档数据库中,它不是这样工作的。完全非规范化意味着在“products”文档中,实际上会有一个值保存实际的类别字符串,从而导致大量重复数据,错误更难纠正。再仔细想想,这难道不意味着运行诸如“给我这个类别的所有产品”这样的查询会导致不完整的结果吗

当然,解决这个问题的方法是在文档数据库中重新实现整个“category_id”,但是当我想到这一点时,我意识到我应该只使用关系数据库,而不是重新实现它们


这让我相信我遗漏了文档数据库的一些关键点,而这些关键点导致我走上了错误的道路。所以我想把它放在堆栈溢出上,我遗漏了什么?

我想说的是,您忽略的第一件事(至少从文章的内容来看)是,文档数据库并不意味着要取代关系数据库。事实上,您给出的示例在关系数据库中非常有效。它应该留在那里。文档数据库只是以另一种方式完成任务的另一种工具,它们并不适合每项任务

文档数据库是为了解决(从另一个角度看)关系数据库不是解决所有问题的最佳方法的问题而创建的。两种设计都有各自的用途,两者都不比另一种好

请查看MongoDB网站上的用例:

完全非规范化意味着在“products”文档中,实际上会有一个值保存实际的类别字符串,从而导致大量重复数据[…]

诚然,非规范化意味着存储额外的数据。它还意味着更少的集合(SQL中的表),从而减少数据片段之间的关系。每个文档都可以包含来自多个SQL表的信息

现在,如果您的数据库分布在多个服务器上,那么查询单个服务器比查询多个服务器更有效。使用文档数据库的非规范化结构,您更可能只需查询单个服务器即可获得所需的所有数据。使用SQL数据库,相关数据可能分布在多个服务器上,这使得查询效率非常低

[…]而且错误更难纠正

也是这样。大多数NoSQL解决方案不能保证引用完整性等SQL数据库所共有的东西。因此,应用程序负责维护数据之间的关系。然而,由于文档数据库中的关系量非常小,所以这并不像听起来那么难

文档数据库的一个优点是它的模式较少。您可以随时完全自由地定义文档的内容;与SQL数据库相比,您不必绑定到预定义的表和列集

现实世界的例子 如果要在SQL数据库上构建CMS,则每个CMS内容类型都有一个单独的表,或者有一个包含通用列的表,在其中存储所有类型的内容。如果使用单独的表,您将拥有大量的表。只要想想您需要的所有连接表,例如每种内容类型的标记和注释。使用单个通用表,应用程序负责正确管理所有数据。此外,数据库中的原始数据很难更新,在CMS应用程序之外也毫无意义

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

忠告 正如您所看到的,SQL和NoSQL解决方案各有优缺点。作为David,每种类型都有其用途。我建议您分析需求并创建两个数据模型,一个用于SQL解决方案,另一个用于文档数据库。然后选择最适合的解决方案,同时牢记可伸缩性。例如,支持无模式、模式完整或混合模式。在某些上下文中,您需要约束、验证等,但您需要在不接触模式的情况下灵活地添加字段。这是一种模式混合模式

例如:

{ “@rid”:10:3, “@class”:“客户”, “@ver”:3, '姓名':'杰伊', “姓氏”:“矿工”, “发明”:[“阿米加”] }

在这个例子中,fiel