案例: 系统中有用户,并且有静态文档(如书籍)每个用户可以使用一些文档,并且每个文档都有特定的状态/设置(如文档,书签/注释中的当前位置/页面)。
使用两个键userId和documentId或者具有_id等于userId的集合以及_id等于documentId的子集文档的嵌套数组(在该场景集合中)是什么更好的方式来存储该用户并将特定信息记录在flat collection中还用于存储非文档特定用户数据)?
1st scenaroio:find({userId:...,documentId:...})
2nd scenaroio:findBy({_ id:...}),然后找到_id等于documentId
的子文档
第一种情景的PROS:
1)我相信更快找到并保存操作。
第一种情景的结论:
1)更多文件
2)无法在集合中存储一些非doc相关的特定于用户的数据
第二种情景的PROS:
1)更好地表示数据关系(主观但是)
2)可以使用相同的集合来存储一些其他非特定文档相关的用户数据。
第二个缺点:
1)更难搜索和更困难的保存操作(我使用的是Mongoose ODM和代码并不复杂),我认为操作的速度比第一种方案快。
需要考虑的一些事项:
1)通常在读取操作中,我只选择一个文档特定数据
2)我需要OFTEN来保存一个文档特定数据(例如在用户正在使用的文档中定期保存位置)。
3)用户/文档状态可能有一些必须更改的嵌套数组(书签,注释)(插入/删除文档)
考虑到这一点,我会说第一种情况更适合这项任务,但我想听一些专家意见,两种情况是否有很大不同。
答案 0 :(得分:1)
您的实际访问路径是什么?您是以用户ID开头,还是查找用户阅读的文档?或者您是从一个文档开始并搜索读取它的用户? 文档对象是轻量级的(只是标题和作者等信息)还是重量级(包含内容)? 如果文档是重量级的,我会将它们保存在一个单独的集合中并转到方案2。
基本上,场景1模仿关系解决方案,场景看起来像对象模型。
我相信对象模型能够更好地描述现实,并且效率更高。
所以我会选择方案2,除非你经常在读者面前搜索一本书。