我已经尝试在 Web 应用程序中仅使用mongodb有一段时间了。但我想知道为什么有些人说无模式或动态模式很强大。现在我不认为它如此美妙或美妙。有人想谈谈使用无模式数据库的正确案例吗?首先我想讲一些我的故事。
什么是无模式、数据库或代码?
大多数 NoSQL 数据库都想说它们是无模式的,但我认为真正重要的部分是在应用程序中运行的代码。
例如,用户信息的存储可以是无模式的,但这并不意味着您可以将用户名存储为对象或将密码存储为时间戳。用户登录代码假设用户名是字符串,密码是哈希。最终这会使数据库存储受限于模式。
嵌入式文档难以维护或查询
我创建了一个 CMS 作为示例来开始我的 NoSQL 数据库生活。一开始帖子和评论数据是这样存储的
[
{
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, ... ]
},
...
]
如您所见,我将评论嵌入到每个帖子的列表中。这非常方便,因为我可以轻松地将新评论附加到任何帖子或随帖子一起检索评论。但是很快我就遇到了第一个问题:从列表中删除某个评论(通常是垃圾邮件)非常麻烦。令我惊讶的是 mongo还没有实现它。
除了 API 级别的问题之外,还很难在集合中查询嵌入的文档。如果我坚持这种设计,以下查询只能以蛮力方式实现
- 最近的评论
- 某个用户的评论
最终,我不得不将评论放入另一个集合中,其中一个post_id
字段存储评论所属的帖子的 id,就像我们在关系数据库中所做的 FK 一样。
尽管有评论设计,但帖子标签还是很有帮助的。
我在这篇文章中找到了一个意见
在 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 完整发送到浏览器时,也会发生类似的事情)
上面的问题让我很困惑。有没有人想谈谈无模式数据库的良好实践,以及在单个应用程序中混合一个关系数据库和一个无模式数据库是否是一个好的决定?