我正在使用Meteor / MongoDB构建一个Web应用程序,该应用程序将拥有大量用户,每个用户将管理一组健康客户端的配置文件数据,并为他们存储相关的配置文件数据,例如"姓名","出生日期"等
目前,我将每个用户的客户数据作为嵌入文档存储在Meteor.users集合中,而不是单独收集用户和客户端(然后在它们之间进行映射)。但我不确定这是正确的做法。
这个应用程序最终将扩展到数千个用户,每个用户拥有约50个客户端,这就是为什么我认为在MongoDB中使用嵌入式文档模型会更快/更好,而不是拥有大量客户端然后映射它们到具有客户端ID的关联用户文档。让我们说10,000个用户,每个用户有50个客户端 - 如果我使用单独的客户端集合,那么在查询期间将遍历500,000个项目,但如果使用仅具有Users集合的嵌入式文档模型,则只有10,000个项目。“ p>
但是要弄清楚Meteor中的发布/订阅内容,使用"用户"数据库,证明有点痛苦。看起来我应该能够创建一个客户端集合,获取用户foo的所有客户端记录子文档,然后将它们填充到Clients集合中。但是a)我无法弄清楚如何做到这一点,并且b)看起来不像MongoDB应该如何工作 - 看起来像是" MongoDB风格"将客户端存储在单独的集合中,并将它们映射到具有ID的关联用户。
当用户拥有可以查看其客户数据的子用户时,可能会有一段时间,因此它开始看起来像是单独的用户和客户端集合"模型更有意义,但数据库中的500,000个项目听起来很多(我没有数据库经验)。
这里有什么建议吗?
答案 0 :(得分:2)
这里有几个问题。我会尽量给出我所看到的尽可能多的答案。
似乎“MongoDB样式”将客户端存储在单独的集合中,并将它们映射到具有ID的关联用户。
通常,mongo倾向于嵌入文档,而流星则喜欢使用较小的细粒度数据。根据你所说的,我会把客户放在他们自己的收藏中,而不是三思而后行。这显然是最灵活的选择。
假设有10,000个用户,每个用户有50个客户端 - 如果我使用单独的客户端集合,则在查询期间将遍历500,000个项目
这就是为什么数据库有indexes的原因。如果一个常见的查询是“给予所有给定用户是经理的客户”。这看起来像是:
Clients.find({manager: userId});
如果Clients
集合没有索引,则每次运行此查询时,它都会执行全表扫描(查看每个文档)。但是,如果在manager
上添加索引,则会立即返回必要的~50个客户端。有关更多示例,请参阅this和this。
但是使用“用户”数据库计算Meteor中的发布/订阅内容确实有点痛苦。
以下是获取当前用户管理的客户端的示例:
Meteor.subscribe('managedClients');
Meteor.publish('managedClients', function () {
return Clients.find({manager: this.userId});
});
答案 1 :(得分:0)
这两种方法在概念上都适用于monog,但是,考虑到你所谈论的数字,我倾向于设置一个模式,通过用户ID链接客户端,而不是将它们存储为子文档。
鉴于您可能需要在多个位置查找客户端,将它们置于用户数据下可能会出现问题。另一方面,如果你总是通过用户ID访问客户端,那么嵌入式方法是有价值的。