1

我正在创建一个需要数据存储的项目,我正在考虑使用 MongoDB,但在找到组织数据的逻辑/最佳方式时遇到了麻烦

我的简化数据需要像这样存储地方信息:

{place_city : "London",
place_owner: "Tim",
place_name: "Big Ben"}

{place_city : "Paris",
place_owner: "Tim",
place_name: "Eifel Tower"}

{place_city : "Paris", 
place_owner: "Ben",
place_name: "The Louvre"}

这是我需要的主要操作

Retrieve all my places
Retrieve all my friends places
Retrieve all my friends cities

如果我使用 mongoDB,集合文档的最大大小是 16meg,对吗?如果这是正确的,那么我不能将所有信息存储在类似于我上面的示例的地方,对吗?

我可能需要创建一个“所有者”集合?像这样:

{
  owner: "Tim", 
  cities: [ {
             name: "London",
             places:[ {name:"Big Ben"}]
            },
            {
             name: "Paris",
             places:[ {name:"Eifel Tower"}, {name: "The Louvre"}]
            }
           ]
}

但现在的问题是检索我朋友的位置变得很麻烦,而我的朋友城市更是如此......

来自狡猾的数据库架构师的任何建议都将不胜感激。

4

3 回答 3

1

数据大小限制是每个文档而不是每个集合。集合很容易变成数 GB(甚至 TB)大。

我建议您保持数据尽可能简单,例如:

{place_city : "London",
place_owner: "Tim",
place_name: "Big Ben"}

{place_city : "Paris",
place_owner: "Tim",
place_name: "Eifel Tower"}

{place_city : "Paris", 
place_owner: "Ben",
place_name: "The Louvre"}

我在想朋友是这样存储的:

{
     username: "Ben",
     friends: [ "Tim", "Bob" ]
}

然后您的三个查询可以完成为:

  1. 你所有的地方:db.places.find( { place_owner: "Ben" } );
  2. 你所有朋友的地方有两个查询(伪代码):

    friends = db.friends.find( { username: "Ben" } );
    // friends = [ "Tim", "Bob" ], you do need to do some code to make this change
    db.places.find( { place_owner: { $in: [ "Tim", "Bob" ] } } );
    
  3. 你所有朋友的城市有两个查询(伪代码):

    friends = db.friends.find( { username: "Ben" } );
    db.so.distinct( 'name', { place_owner: { $in: [ "Tim", "Bob" ] } } );
    

即使有数百万个文档,这也应该可以正常工作,前提是您在查询的字段上有一个索引:{ place_owner: 1 }{ username: 1 }.

于 2013-08-15T14:59:42.820 回答
1

16MB 的大小限制是每个文档,而不是每个集合。

{place_city : "London", place_owner: "Tim", place_name: "Big Ben"}

是一个很小的文件,所以不用担心。集合的设计很大程度上取决于您查询数据的方式。

于 2013-08-15T13:16:49.543 回答
0

我喜欢 MongoDB,但这个数据不是 MongoDB 的好候选。MongoDB 不支持关系,这基本上就是您在此处跟踪的全部内容。使用关系数据库来存储关系。

可以这样想:在 DBMS、MongoDB 或 SQL 的皮肤下,索引是索引,表是表(基本上)。您可以从 MongoDB 获得更高的性能,不是因为它可以更快地完成相同的事情,而是因为您可以使用它来让您的数据库服务器做更少的事情。(例如,拉出包含嵌套数组和子文档的整个文档,而不是将一堆表连接在一起)。MongoDB 处理更新的方式存在一些根本差异,但对于查询简单数据集,大多数系统将相对相似。两者之间的一个主要区别在于 MongoDB 的工作方式,它不能将集合中的数据用作另一个查询的参数,这基本上是关系数据库的全部要点。由于您的两个用例需要“加入”(到“我所有的朋友”),因此您需要两个查询。

因此,您对两个查询所做的操作与连接相同,只是关系数据库经过优化以非常有效地执行此操作;我向您保证,手动执行此连接会更慢,而且您正在通过网络发送所有数据(朋友的 ID)并建立额外的数据库连接。现在,如果您可以将所有朋友的城市和地点存储在一个文档中,MongoDB 可能会(稍微)比加入快,但现在您遇到了一个新问题,因为您现在必须随时管理所有这些添加一个城市或地方所有他们的朋友都必须修改——这是不现实的。

但故事远不止这些,因为 SQL DBMS 是非常成熟的应用程序,具有许多提高查询性能的功能。他们让你做一些事情,比如创建“物化视图”,将你所有的朋友城市和地点存储在内存中,并在他们的源表之一更新时自动更新,这样你就不必做任何特别的事情,你只需查询并且您无需实际执行任何连接即可获取数据。(物化表在这里不合适,但仅作为示例,如果您需要它是可能的。)

此外,当您使用 MongoDB 时,我发现有一条很有帮助的指南,每当您问自己文档是否足够大以存储您最终拥有的所有数据时,您可能会遇到设计问题。如果文档的增长不受约束,则可能应该在集合中枚举它。或者换一种说法,你的集合应该随着你的应用程序的使用而增长,而不是你的文档的大小(很多)。

如果像这样拆分架构意味着对于主要操作,您需要进行大量手动连接,那么值得考虑是否应该使用关系数据库来代替。

于 2013-08-15T13:20:43.003 回答