所以我在Meteor编写应用程序,这是我学院的一个迷你社交网络。我现在面临的问题是我的数据是关系型的。 这个网络应用程序允许人们写帖子和发布图像和链接。关注用户的人会在他的Feed上看到他的帖子。人们可以分享这个。所以数据是相互连接的。
所以基本上
答案 0 :(得分:1)
在开始建模数据之前,您已经做了第一步 - 也是正确的 - 定义用例的步骤。
但是,您误以为相互关联的数据需要RDBMS。
model relationships between documents有几种方式。
注意:为了简洁和易于理解,以下示例进行了大量简化
1:1的关系可以简单地通过嵌入来建模:
func fillAnObjectClassArrayGivenURL<T: AnyObject>(urlString: String, className: T.Type) -> [T]
1:许多关系也可以通过嵌入来建模:
{
_id: "joe",
name: "Joe Bookreader",
address: {
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
}
与RDBMS相比的主要区别在于您解析了应用程序代码中的引用,如下所示。
隐式引用假设我们有出版商和书籍。发布商文档可能如下所示
{
_id: "joe",
name: "Joe Bookreader",
phone:[
{ type:"mobile", number:"+1 2345 67890"},
{ type:"home", number:"+1 2345 987654"}
]
}
和书籍文档可能看起来像这样
{
_id: "acme",
name: "Acme Publishing, Inc."
}
现在重要的部分是:我们基本上有两个用例可以覆盖这些数据。
是第一个对于“The Book of Foo”,请获取发布者的详细信息
很简单,因为我们已经拥有“The Book of Foo”及其价值
{
_id:"9788636505700",
name: "The Book of Foo",
publisher: "acme"
}
另一个用例是
Acme Publishing,Inc。出版了哪些书籍?
由于我们再次获得Acme Publishing公司的数据,这很容易:
db.publishers.find({_id:"acme"})
MongoDB 具有引用的概念,通常称为DBRefs
但是,这些引用由驱动程序而不是MongoDB服务器解析。就个人而言,我从未使用或需要它,因为大多数时候隐式引用都能很好地工作。
假设我们有一个像
这样的用户文档db.books.find({publisher:"acme"})
当天真地这样做时,我们只需将帖子嵌入用户文档中。
但是,这会限制一个人可以发布的帖子数量,因为BSON文件的硬编码大小限制为16MB。
因此,很明显每个帖子都应该有自己的文档,并引用作者:
{
_id: "joe",
name: "John Bookreader",
joined: ISODate("2015-05-05T06:31:00Z"),
…
}
然而,这带来了一个问题:我们想要显示作者姓名,而不是他的身份。 对于单个帖子,我们可以简单地在users集合中进行查找以获取名称。但是当我们想要显示帖子列表时呢?这需要大量的查询。因此,我们使用冗余来保存这些查询并优化我们的应用程序:
{
_id: someObjectId,
title: "My first post",
text: "Some text",
author: "joe"
}
因此,对于帖子列表,我们可以使用海报的名称显示它们,而无需其他查询。只有当用户想要获得有关海报的详细信息时,您才能通过他的身份查找海报。通过这种方式,我们为常见用例保存了大量查询。您可以说“停止!如果用户更改了他的名字该怎么办?”嗯,对于初学者来说,这是一个相对罕见的用例。即使在什么时候,它也不是什么大问题。首先,我们必须更新用户文档:
{
_id: someObjectId,
title: "My first post",
text: "Some text",
author: { id:"joe", name: "Joe Bookreader"}
}
然后,我们必须采取额外措施:
db.users.update({"_id":"joe"},{$set:{name:"Joe A. Bookreader"}})
当然,这有点贵。但是我们在这做了什么?我们以一个相当罕见的用例为代价优化了一个常见用例。在我的书中讨价还价。
我希望这个简单的例子可以帮助您更好地理解如何使用MongoDB处理应用程序的用例。