2

我已经尝试在 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 完整发送到浏览器时,也会发生类似的事情)

上面的问题让我很困惑。有没有人想谈谈无模式数据库的良好实践,以及在单个应用程序中混合一个关系数据库和一个无模式数据库是否是一个好的决定?

4

2 回答 2

1

当在具有继承的面向对象上下文中使用它们时,无模式数据库的主要优势就显现出来了。

继承意味着您拥有的对象具有一些共同的属性,但也有一些特定于对象子类型的属性。

例如,想象一下计算机硬件商店的产品目录。

每个产品都会有属性name,vendorprice。但是 CPU 将有一个clock_rate,硬盘将有一个capacity,RAMcapacityclock_rate网卡都有一个bandwidth。在关系数据库中执行此操作会留下两个同样麻烦的选项:

  1. 为所有可能的属性创建一个包含字段的表,但对于不适用的产品,将它们中的大多数保留为 NULL。
  2. product_attributesproductId,attribute_name和创建一个辅助表 " attribute_value"

另一方面,无模式数据库很容易允许将具有不同可选属性集的项目存储在同一集合中。将产品属性呈现为 HTML 的代码将检查每个已知的可选属性是否存在,然后调用适当的函数,将其值作为表格行输出。

无模式数据库的另一个优点是它在开发过程中提供了额外的敏捷性。它可以让您轻松尝试新功能,而无需重新构建数据库。这使得维护与应用程序先前版本创建的数据的向后兼容性变得非常容易,而无需运行复杂的数据库转换例程。我目前正在使用 MongoDB 开发 MMORPG。在开发过程中,我添加了许多新功能,这些新功能需要将每个字符的新数据保存在数据库中。我从来不需要在我的数据库上运行一个等同于 CREATE TABLE 或 ALTER TABLE 的命令。MongoDB 只是吃掉了我扔给它的任何数据。我的第一个测试角色仍然可以玩,尽管我从未有意升级到它的数据库文档。

于 2013-05-07T14:12:16.963 回答
0

在关系数据库中执行此操作会留下两个同样麻烦的选项:

我猜这里还有一个选择。以 xml 格式添加数据,并让应用程序以它想要的方式对其进行反序列化/序列化。

于 2013-05-18T12:28:12.187 回答