我正在进行动态数据存储,它位于关系数据库中:
form -> field
form -> form_data
field -> field_data
form_data -> filed_data
和字段数据包含field_id,form_data_id和value
但是为了扩展性和性能,我计划将form_data和field_data移动到MongoDB,我现在的问题是如何设计MongoDB集合,使用一个集合用于所有form_data并移动field_data以在其中映射,key是field_id,value是这个field_data的值,或者为每个表单记录和存储数据的集合直接在form_data中没有map,因为在这种情况下所有数据都是一致的。
答案 0 :(得分:1)
在像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
{}的子对象相同的键。 {1}}并存储用户在该表单中创建的条目。
如果您的用例需要频繁访问汇总数据(例如,您希望在公共网站上发布最新统计信息),您还可以将此信息存储在forms
字段中避免对许多forms
文档进行昂贵的聚合查询。 MongoDB通常建议根据您的性能要求而不是数据的语义来定位数据库模式。
关于您的评论“此案例中的所有数据都将保持一致”:请记住,MongoDB不会强制执行参照完整性。当应用程序删除或更改文档时,应用程序有责任在其他文档中修复对其的任何过时引用。