【发布时间】:2013-05-01 07:24:16
【问题描述】:
我已经尝试在 Web 应用程序中仅使用 mongodb 有一段时间了。但我想知道为什么有些人说无模式或动态模式很强大。现在我不认为它如此美妙或美妙。有人想谈谈使用无模式数据库的正确案例吗?首先我想讲一些我的故事。
什么是无模式、数据库或代码?
大多数 NoSQL 数据库都想说它们是无模式的,但我认为重要的部分是在应用程序中运行的代码。
例如,用户信息的存储可以是无模式的,但这并不意味着您可以将用户名存储为对象或将密码存储为时间戳。用户登录代码假定用户名是字符串,密码是哈希值。最终,数据库存储受限于模式。
嵌入式文档难以维护或查询
我创建了一个 CMS 作为示例来开始我的 NoSQL 数据库生活。一开始posts和cmets数据是这样存储的
[
{
title: 'Mongo is Good',
content: 'Mongo is a NoSQL database.',
tags: ['Database', 'MongoDB', 'NoSQL'],
comments: [ COMMENT_0, COMMENT_1, ... ]
},
{
title: 'Design CMS',
content: 'Design a blog or something else.',
tags: ['Web', 'CMS'],
comments: [ COMMENT_2, COMMENT_3, ... ]
},
...
]
如您所见,我将 cmets 嵌入到每个帖子的列表中。这非常方便,因为我可以轻松地将新评论附加到任何帖子或随帖子一起检索 cmets。但是很快我就遇到了第一个问题:从列表中删除某个评论(通常是垃圾邮件)非常麻烦。令我惊讶的是 mongo haven't still implemented it。
除了 API 级别的问题之外,还很难跨集合查询嵌入的文档。如果我坚持这种设计,以下查询只能以暴力方式实现
- 最近的cmets
- 某个用户的cmets
最终我不得不将 cmets 放入另一个集合中,使用 post_id 字段存储评论所属帖子的 id,就像我们在关系数据库中所做的 FK 一样。
尽管采用 cmets 设计,但帖子标签还是很有帮助的。
我在this post找到了意见
在 NoSQL 中,您不会根据数据实体之间的关系来设计数据库。您可以根据将针对它运行的查询来设计数据库。
但是需求的变化呢?仅仅因为应该支持一个新的查询就重构一个数据库是不是太疯狂了?
这些案例值得无架构
在其他一些需要无架构存储的情况下。例如,类似推特的时间线,数据格式如下
[
{
_id: ObjectId('aaa'),
type: 'tweet',
user: ObjectId('xxx'),
content: '0000',
},
{
_id: ObjectId('bbb'),
type: 'retweet',
user: ObjectId('yyy'),
ref: ObjectId('aaa'),
},
...
]
问题在于将文档呈现为 HTML 并不是一件容易的事。我以这种方式渲染它们(Python)
renderMethods = {
'tweet': render_tweet,
'retweet': render_retweet,
}
result = [ render_methods[u['type']](u) for u in updates ]
因为只存储 JSON 数据,而不是成员函数。结果,我必须根据其类型手动将渲染函数映射到每个更新。 (当服务器通过 AJAX 将 JSON 完整发送到浏览器时也会发生类似的事情)
上面的问题让我很困惑。有没有人想谈谈无模式数据库的良好实践,以及在单个应用程序中混合一个关系数据库和无模式数据库是否是一个好的决定?
【问题讨论】:
-
您的帖子读起来更像是对 mongodb 无模式概念的咆哮,而不是一个问题。我只是没有反对它,因为它是一个格式正确且语法正确的咆哮:)
标签: database nosql schema schema-design