我一直在关注NoSql运动的兴起以及随之而来的mongodb,ravendb等文档数据库的普及.虽然我喜欢这些有很多相关的东西,但我觉得我并不理解一些重要的东西.
假设您正在实现商店应用程序,并且您希望存储在数据库产品中,所有这些产品都有一个唯一的类别.在关系数据库中,这可以通过具有两个表,产品和类别表来完成,并且产品表将具有一个字段(可能称为"category_id"),该字段将引用具有正确类别条目的类别表中的行.这有几个好处,包括不重复数据.
这也意味着,如果拼错了类别名称,例如,您可以更新类别表,然后将其修复,因为这是唯一存在值的地方.
但是,在文档数据库中,这不是它的工作原理.你完全非规范化,意味着在"产品"文档中,你实际上会有一个保存实际类别字符串的值,导致大量重复数据,并且错误更难以纠正.更多地考虑这个问题,是否也意味着运行诸如"给我这个类别的所有产品"之类的查询可能导致没有完整性的结果.
当然,解决这个问题的方法是在文档数据库中重新实现整个"category_id"事物,但是当我想到这一点时,我意识到我应该继续使用关系数据库而不是重新实现它们.
这让我相信我错过了关于文档数据库的一些关键点,这些关键点导致我走上了这条不正确的道路.所以我想把它放到堆栈溢出,我错过了什么?
你完全反规范化,意思是在"产品"文档中,你实际上有一个值保存实际的类别字符串,导致大量重复数据[...]
是的,非规范化意味着存储额外的数据.它还意味着更少的集合(SQL中的表),从而减少了数据之间的关系.每个单个文档都可以包含来自多个SQL表的信息.
现在,如果您的数据库分布在多个服务器上,则查询单个服务器而不是多个服务器会更有效.使用文档数据库的非规范化结构,您更有可能只需查询单个服务器即可获得所需的所有数据.使用SQL数据库,您的相关数据可能会分布在多个服务器上,从而使查询效率非常低.
[...]错误更难以纠正.
也是如此.大多数NoSQL解决方案都不保证参考完整性等内容,这些内容对SQL数据库来说很常见.因此,您的应用程序负责维护数据之间的关系.但是,由于文档数据库中的关系量非常小,因此并不像听起来那么难.
文档数据库的一个优点是它没有模式.您可以随时自由定义文档的内容; 与SQL数据库一样,您不依赖于预定义的表和列集.
如果您在SQL数据库之上构建CMS,则要么为每个CMS内容类型都有一个单独的表,要么为具有通用列的单个表存储所有类型的内容.使用单独的表,您将拥有大量表.想想你需要的所有连接表,比如每种内容类型的标签和注释.使用单个通用表,您的应用程序负责正确管理所有数据.此外,数据库中的原始数据很难更新,并且在CMS应用程序之外没有任何意义.
使用文档数据库,您可以将每种类型的CMS内容存储在单个集合中,同时在每个文档中保持强定义的结构.您还可以在文档中存储所有标记和注释,从而使数据检索非常高效.这种效率和灵活性需要付出代价:您的应用程序更负责管理数据的完整性.另一方面,与SQL数据库相比,使用文档数据库扩展的价格要低得多.
如您所见,SQL和NoSQL解决方案都有优点和缺点.正如大卫已经指出的那样,每种类型都有其用途.我建议您分析您的需求并创建两个数据模型,一个用于SQL解决方案,另一个用于文档数据库.然后选择最适合的解决方案,牢记可扩展性.
我要说的是,你忽略的第一件事(至少根据帖子的内容)是文档数据库并不是要取代关系数据库.事实上,您提供的示例在关系数据库中工作得非常好.它可能应该留在那里.文档数据库只是以另一种方式完成任务的另一种工具,它们不适合于每项任务.
文档数据库是为了解决(以相反的方式查看)问题,关系数据库不是解决每个问题的最佳方法.两种设计都有它们的用途,它们本身都不比另一种好.
看一下MongoDB网站上的用例:http://www.mongodb.org/display/DOCS/Use+Cases