这个结构是否可以用MongoDB实现?

时间:2016-04-16 12:59:34

标签: mongodb meteor social-networking meteor-accounts database

所以我在Meteor编写应用程序,这是我学院的一个迷你社交网络。我现在面临的问题是我的数据是关系型的。 这个网络应用程序允许人们写帖子和发布图像和链接。关注用户的人会在他的Feed上看到他的帖子。人们可以分享这个。所以数据是相互连接的。

所以基本上

  1. 用户有关注者
  2. 关注者从他们关注的人那里获取帖子
  3. 他们可以评论和分享
  4. 共享帖子出现在关注分享者的人
  5. 每个帖子都应该使用预定义的标签进行标记
  6. 关注代码的用户应该获得带有代码的帖子,无论他们是否跟踪撰写帖子的人员

1 个答案:

答案 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处理应用程序的用例。