所以我有一些关于公司很多人的数据,比如姓名,年龄和性别。我将把他们的信息存储在MongoDB中。我将它们的信息存储在很多文档中或作为一堆独立的对象存储在一个文档中会不会更好?是否有任何性能或内存问题会使一种方法优于另一种方法?
存储数据的示例方法:
大量文件
{
_id: ObjectId('1'),
name: 'Bart',
age: 10,
gender: 'Male'
},
{
_id: ObjectId('2'),
name: 'Lisa',
age: 8,
gender: 'Female'
}
一个文档中的大量对象
{
_id: ObjectId('1'),
'Bart': {
age: 10,
gender: 'Male'
},
'Lisa': {
age: 8,
gender: 'Female'
}
}
对于任何想知道我用Mongo的投影参数查询第二个例子的人,例如
db.families.find({_id:ObjectId('1')},{_id:0,'Bart':1});
另外,我问这个的唯一原因是因为我打算在这里存储来自多家公司的人。它们将通过集合和单独列出的人员分开,如第一个示例或文档中的文档以及单独列为公司文档中的对象的人员。
答案 0 :(得分:4)
第一个是可取的。
每个文档都有16 MB的限制。因此,将所有内容放在单个文档中更有可能遇到这个障碍,您必须手动执行文档拆分,并最终获得同一(伪)集合的多个文档。您需要额外的程序代码才能找到正确的片段,甚至可以将应用程序中的文档组合起来执行一些集合级操作。除非有非常这样做的理由,否则我会不惜一切代价避免这种情况。
此外,它可能最适合您的访问模式。您还有更多优化选项,例如您可以在名称上定义索引,而第二个示例无法做到。同样,文档越小,更新该文档的速度就越快(特别是在没有就地更新的情况下)。
如果您打算让多个公司拥有用户,您可以为每个公司使用单独的集合,也可以在文档中添加公司属性。这取决于你将支持多少公司,但假设它不只是2或3,我更喜欢后一种选择。它更易于维护,缩放(即分片),优化(索引等)或扩展。
{
_id: ObjectId('1'),
name: 'Bart',
age: 10,
gender: 'Male'
company: 'XYZ'
}
修改强>:
有关性能的更多考虑因素。两种选择的基本事件流程如下:
1-doc策略(带投影)
n-doc策略(无投影)
特别是对于1-doc策略,当它比n-doc策略慢时,可能会有一个转折点,特别是当文档变大时。对于较小的文档,它可能相同或者更快,特别是当缓存发挥作用或其他边缘情况发生时(即名称范围有限,这使得对名称的查询不是很有选择性,但在这种情况下你会被搞砸无论如何使用1-doc方法)
Mongo对模式设计的建议如下:
你打算做的是建立公司:人际关系,这可能是第三种或第二种选择。所以要么你有两个集合:
或
无论哪种方式,我都会将此人塑造为
person:
{
_id: ObjectId('1'),
name: 'Bart',
age: 10,
gender: 'Male'
company: 'XYZ' //only for foreign key relationship to separate collection
}
对于嵌入式人员,它是公司中的阵列
company:
{
name: 'companyA',
persons: [..] //and not use person's name as key here
}
我可以在persons.name
和/或company
上添加索引。因此,搜索单个人完全在内存中运行(使用索引)并且加载人员文档应该很快,因为只从光盘读取一个小文档。
因此,这些方法中的任何一种都为我提供了最高的灵活性,同时仍然非常快速地访问。
虽然可能存在这样的情况,但是当投影速度很快时(可能是在拥有小型公司"文件且已经缓存的情况下),我不会这样做,因为它有一些严重的缺点(其中一些也会对性能产生负面影响)。
因此,即使没有证明一个appproach比另一个更快,我也不会采用预测方法来过滤用户,因为这些缺点远远超过了(假设的)优势。