在像 MongoDB 这样的面向文档的数据库中,您应该始终支持聚合而不是引用,因为它们不支持数据库上的 JOIN 操作来链接多个文档。
这意味着两个实体之间的“A 有许多 B”关系不应建模为两个表 A 和 B,而是建模为 A 的一个集合,其中每个 A 都有一个嵌入的 B 对象数组。
然而,在 MongoDB 的上下文中,还有一个额外的限制:MongoDB 不喜欢增长的对象。当一个对象在其生命周期内积累越来越多的数据时,该对象就会增长。这意味着MongoDB为其分配的硬盘空间将一次又一次地用完,这将需要重新分配空间。这需要性能和数据库碎片。此外,MongoDB 对文档有一个人为的大小限制,主要是为了阻止开发人员设计不断增长的对象。
为此:
当数据在创建时存在时,直接嵌入。
当创建后添加的数据越来越多时,将其放入不同的集合中。
当表单有 X 个字段时,字段的数量在其生命周期内可能不会发生太大变化。因此,您应该将字段及其描述直接嵌入到表单对象中。
但是输入这些表单的答案数量会随着时间的推移而增加,这意味着这些应该被视为单独集合中的单独对象。
所以我建议你有两个集合,forms
和form_data
。
每个文档都嵌入了一个具有静态字段属性forms
的子对象。fields
每个文档form_data
都有一个带有相应表单的_id的字段,并嵌入一个子对象,该子对象使用与子对象field_data
相同的键,并存储用户在该表单中所做的条目。fields
forms
当您的用例需要频繁访问聚合数据时(例如,当您想在公共网站上发布最新统计数据时),您还可以将此信息存储forms
在form_data
文件。MongoDB 通常建议您根据您的性能要求而不是数据的语义来定位您的数据库模式。
关于您的评论“这种情况下的所有数据都将是一致的”:请记住,MongoDB 不强制执行参照完整性。当应用程序删除或更改文档时,应用程序有责任修复其他文档中对它的任何过时引用。