Mongodb NoSql参考数据

Mongodb NoSql参考数据,mongodb,cassandra,couchdb,nosql,Mongodb,Cassandra,Couchdb,Nosql,免责声明:我所说的参考数据并不是指参考完整性 我正在学习nosql,希望了解数据应该如何建模。例如,在CMS应用程序的典型关系数据库中,您可能有两个表:article和author,其中article引用了author 在nosql系统中,您可以通过这种方式创建文章文档,因为它们只是 等等 比如有一天,Smarty Pants先生决定将自己的名字改为普通的Joe,因为nosql已经无处不在。在这种情况下,需要扫描每篇文章并更新作者姓名 因此,我的问题是,如何在NoSQL中建模数据以适合CMS的基

免责声明:我所说的参考数据并不是指参考完整性

我正在学习nosql,希望了解数据应该如何建模。例如,在CMS应用程序的典型关系数据库中,您可能有两个表:article和author,其中article引用了author

在nosql系统中,您可以通过这种方式创建文章文档,因为它们只是

等等

比如有一天,Smarty Pants先生决定将自己的名字改为普通的Joe,因为nosql已经无处不在。在这种情况下,需要扫描每篇文章并更新作者姓名

因此,我的问题是,如何在NoSQL中建模数据以适合CMS的基本用例,以便<强>性能比RDBMS 快或快?例如,声称CMS是一个用例

编辑

很少有人建议对数据进行标准化,例如:

article 
{
title: "Death to RDBMS",
slug: "rdbms_sucks", 
author: {id: "10000001"}
}

author
{
name: "Big Brother",
id: "10000001"
}
但是,由于nosql在设计上缺乏连接,因此必须使用类似mapreduce的函数将数据汇集在一起。如果这是您的建议,请对此类操作的性能进行评论

编辑2:

如果您认为nosql不适合于需要引用数据的任何类型的数据,请解释原因。这似乎使nosql的用例变得相当有限,因为任何合理的应用程序都会包含关系数据

编辑3:


请允许我声明,我无论如何都不是NoSQL专家。相反,我对它的了解主要是理论性的

也就是说,我坚信在NoSQL中实现这样一个CMS类型的系统可能不是最好的方法,因为数据主要是关系型的

我对这个问题的看法是基于这样的假设:您使用的NoSQL系统允许通过“主键”类型的结构加载记录。我想大多数人都会,但我肯定有些人不会

也就是说,我建议按以下方式存储数据

对于作者:

{
_KEY: $AUTHOR_GUID,
firstName: "Smarty",
lastName: "Pants",
}
至于邮报本身:

{
title: "Learn nosql in 5 minutes",
slug: "nosql_is_easy", 
author: $AUTHOR_GUID,
}
注意,在上面,我使用_KEY表示这是“主键”类型的值


加载文章后,您可以根据作者的GUID加载作者。

对于特定情况,请使用模式,存储对象id而不是对象实体

article 
{
title: "Death to RDBMS",
slug: "rdbms_sucks", 
author: {id: "10000001"}
}

author
{
name: "Big Brother",
id: "10000001"
}

对于一般的mongodb模式设计建议,请阅读

我假设CouchDB是一个NoSQL数据库,如果您这样说的话

但实际上,我们有通用编程语言和领域特定语言。类似地,CouchDB是一个特定于域的数据库

我经常使用CouchDB,但我真的不在乎它是使用SQL还是NoSQL。CouchDB是有价值的(对我来说),因为API是100%HTTP、JSON和Javascript。您可以使用浏览器从CouchDB获取HTML,然后通过AJAX查询数据来构建web应用程序。说这是“不是SQL”是轻描淡写

不管怎样,回到Smarty裤子和普通Joe。也许他有10万份文件。如果我们只是更新了它们,那怎么办?这是一个相当小的Javascript量

$.getJSON('/db/_design/cms/_view/by_user?key=Smarty+Pants', {
  success: function(result) {
    // Change the name right here, in the result objects.
    var docs = result.rows.map(function(row) {
      row.value.firstName = "Regular";
      row.value.lastName = "Joe";
      return row.value;
    })

    // Store it!
    $.post('/db/_bulk_docs', {"docs":docs}, function() {
      console.log("Done! Renamed Smarty Pants in " + docs.length + " documents!");
    })
  }
})
是的,这项技术会让你在计算机科学课上得F。然而,我喜欢它。我会用Firebug编写这段代码。在我的浏览器中。重命名不是原子的,并且没有引用完整性。另一方面,它可能会在几秒钟内完成,没有人会在意

你可能会说CouchDB在流行语和基准测试方面失败了,但却在困难的学校中取得了优异的成绩


另外,
by_user
视图是从map reduce构建的。在CouchDB中,MapReduce是增量的,这意味着它的性能与大多数SQL索引类似。所有查询都会在一个短的、可预测的(对数)时间内完成。

您的数据显然是相关的:一篇文章有作者。您可以在NOSQL存储(如MongoDB)中对数据进行建模,方法与在关系存储中相同,但由于数据库中没有连接,您必须对数据库进行两次调用,因此您没有获得任何结果

但是。。。使用NOSQL存储所能做的是在一定程度上对数据进行非规范化,以获得更好的性能(只需一次往返,即可获得显示文章所需的所有内容),但要以牺牲即时一致性为代价:以始终准确的作者名换取最终准确的作者名

例如,您可以在文章中使用:

author: {firstName: "Smarty", lastName: "Pants", _id:DE342624EF }
现在,您可以非常快速地显示文章,当有人更改了他们的姓名时,您可以启动后台任务来更新所有现有的文章,也可以等待定期的一致性扫描来修复它


许多主要网站不再提供即时一致性。你所做的一些更改最终只能被网站上的其他用户看到。

这篇文章在这里已经有一段时间了,但我想我应该指出另一种使用CouchDB处理“连接”和跨文档引用的方法。这是我在CMS中使用的一种方法,我正在(重新)编写它以使用CouchDB(以前它是为MySQL编写的)

CMS名为BlueInk,可以在Github上找到。目前,重写的重点是文档设计和“渲染引擎”部分,因此没有UI可言——您必须手工制作所有JSON。这是我希望尽快解决的问题,但是repo(一旦安装到CouchDB中)中已经有足够的内容让您了解“连接”是如何完成的

在BlueInk中,页面引用的内容项本身可以包含在一个或多个页面(或同一页面多次)中。页面通过其ID引用页面项(如第二个JSON示例)。当通过运行时,它将生成可与CouchDB的
?include_docs=true
查询参数一起使用的输出,以提取页面文档中内容项引用的完整内容

然后将视图输出传递给
author: {firstName: "Smarty", lastName: "Pants", _id:DE342624EF }