为什么或为什么不使用无架构数据库?

时间:2013-05-07 11:02:04

标签: database nosql schema schema-design

我曾尝试在网络应用中使用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 haven't still implemented it

除了API级问题之外,还很难在整个集合中查询嵌入式文档。如果我坚持这种设计,以下查询只能以强力方式实施

  • 最近的评论
  • 某个特定用户的评论

最终我不得不将评论放入另一个集合中,其中post_id字段存储评论所属的帖子的ID,就像我们在关系数据库中所做的那样。

尽管有评论设计,但帖子标签非常有用。

我在this post

中找到了一个意见
  

在NoSQL中,您不会根据数据实体之间的关系设计数据库。您可以根据要针对它运行的查询来设计数据库。

但是要求的变化怎么样?仅仅因为应该支持新的查询而重构数据库是否过于苛刻?

案例值得无架构

在其他一些需要无架构存储的情况下。例如,类似Twitter的时间轴,数据采用以下格式

[
{
    _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发送到浏览器时会发生类似的事情)

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

2 个答案:

答案 0 :(得分:1)

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

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

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

每个产品都有namevendorprice属性。但CPU将为clock_rate,硬盘驱动器将为capacity,RAM为capacityclock_rate,网卡为bandwidth。在关系数据库中执行此操作会留下两个同样繁琐的选项:

  1. 创建一个包含所有可能属性的字段的表,但对于不适用的产品,大多数都是NULL。
  2. 使用product_attributesproductIdattribute_name创建辅助表格“attribute_value”。
  3. 另一方面,无模式数据库可以轻松地将项目存储在具有不同可选属性集的同一集合中。然后,将产品属性呈现为HTML的代码将检查每个已知可选属性是否存在,然后调用适当的函数,将其值作为表行输出。

    无模式数据库的另一个优点是它在开发过程中提供了额外的灵活性。它可以让您轻松地尝试新功能,而无需重新构建数据库。这使得很容易保持与先前版本的应用程序创建的数据的向后兼容性,而无需运行复杂的数据库转换例程。我目前正在使用MongoDB开发MMORPG。在开发过程中,我添加了许多新功能,这些功能需要在数据库中保留每个字符的新数据。我从来没有必要在我的数据库上运行一个等同于CREATE TABLE或ALTER TABLE的命令。 MongoDB只是吃掉了它,并且喷出了我投入的任何数据。我的第一个测试角色仍然可以播放,虽然我从未有意图升级到其数据库文档。它有一些过时的字段,这些字段是我丢弃或重构的功能的残余,但这些根本不会受到伤害 - 这些过时的字段会很有用,但是当我的玩家为了恢复我删除的功能而尖叫时。

答案 1 :(得分:0)

  

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

我猜这里还有一个选项。 以xml格式添加数据,让应用程序按照自己的方式反序列化/序列化。