我正在创建一个需要数据存储的项目,我正在考虑使用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”系列?像这样:
{
owner: "Tim",
cities: [ {
name: "London",
places:[ {name:"Big Ben"}]
},
{
name: "Paris",
places:[ {name:"Eifel Tower"}, {name: "The Louvre"}]
}
]
}
但现在的问题是,检索我朋友的地方变得很麻烦,我的朋友们的城市更是如此......
来自狡猾的DB建筑师的任何建议都会非常感激。
答案 0 :(得分:1)
每个文档的大小限制为16MB,而非每个集合。
{place_city : "London", place_owner: "Tim", place_name: "Big Ben"}
是一个非常小的文档,所以不要担心。集合的设计在很大程度上取决于您查询数据的方式。
答案 1 :(得分: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" ]
}
然后您的三个查询可以完成:
db.places.find( { place_owner: "Ben" } );
所有朋友的地方有两个查询(伪代码):
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" ] } } );
所有朋友的城市有两个查询(伪代码):
friends = db.friends.find( { username: "Ben" } );
db.so.distinct( 'name', { place_owner: { $in: [ "Tim", "Bob" ] } } );
即使有数百万个文档,这应该可以正常工作,只要您在查询的字段上有索引:{ place_owner: 1 }
和{ username: 1 }
。
答案 2 :(得分:0)
我喜欢MongoDB,但这些数据不适合MongoDB。 MongoDB不支持关系,这基本上就是你在这里跟踪的所有内容。使用关系数据库来存储关系。
可以这样想:在DBMS,MongoDB或SQL的皮肤下,索引是索引,表是表(基本上)。从MongoDB获得更多性能不是因为它可以更快地完成同样的事情,而是因为您可以使用它来让您的数据库服务器做得更少。 (例如,拉出包含嵌套数组和子文件的整个文档,而不是将一堆表连接在一起)。 MongoDB处理更新的方式有一些根本区别,但是对于查询简单数据集,大多数系统都会相对类似。根植于MongoDB工作方式的两者之间的一个很大区别是,它不能将集合中的数据用作另一个查询的参数,这基本上是关系数据库的全部要点。由于您的两个用例需要“加入”(对于“我的所有朋友”),因此您需要两个查询。
因此,您对两个查询所做的事情与连接相同,除了关系数据库经过优化以极其有效地执行此操作;我保证你手动加入会更慢,而且你通过网络发送所有数据(朋友的ID)并建立额外的数据库连接。现在,如果您可以将所有朋友的城市和地点存储在一个文档中,MongoDB可能会(稍微)加入,但现在您遇到了一个新问题,因为您现在必须管理所有这些,任何时候任何人添加一个城市或地方所有的朋友都必须修改 - 这是不现实的。
但故事还有更多,因为SQL DBMS是非常成熟的应用程序,具有许多提高查询性能的功能。他们允许你做一些事情,比如创建“物化视图”,将所有朋友的城市和地点存储在内存中,并在任何一个源表更新时自动更新,这样你就不需要做任何特殊的事情了,你只需要查询并且您无需实际执行任何连接即可获取数据。 (物化表不适合这里,但作为一个例子,如果你需要它,它是可能的。)
另外,当您使用MongoDB时,我发现有用的指导原则是,只要您自问您的文档是否足够大以存储您将会拥有的所有数据,您可能会遇到设计问题你的双手。如果文档的增长未绑定,则应该在集合中枚举它。换句话说,您的馆藏应该随着您的应用程序的使用而增长,而不是文档的大小(很多)。
如果像这样拆分你的架构意味着对于主要操作你正在进行大量的手动连接,那么值得考虑你是否应该使用关系数据库的问题。