0

我正在制作动态数据存储,它在关系数据库中为:

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 在其中映射,键是 field_id,值是这个 field_data,或者为每个表单记录进行收集并将数据直接存储在 form_data 中而不使用映射,因为这种情况下的所有数据将是一致的。

4

1 回答 1

1

在像 MongoDB 这样的面向文档的数据库中,您应该始终支持聚合而不是引用,因为它们不支持数据库上的 JOIN 操作来链接多个文档。

这意味着两个实体之间的“A 有许多 B”关系不应建模为两个表 A 和 B,而是建模为 A 的一个集合,其中每个 A 都有一个嵌入的 B 对象数组。

然而,在 MongoDB 的上下文中,还有一个额外的限制:MongoDB 不喜欢增长的对象。当一个对象在其生命周期内积累越来越多的数据时,该对象就会增长。这意味着MongoDB为其分配的硬盘空间将一次又一次地用完,这将需要重新分配空间。这需要性能和数据库碎片。此外,MongoDB 对文档有一个人为的大小限制,主要是为了阻止开发人员设计不断增长的对象。

为此:

当数据在创建时存在时,直接嵌入。

当创建后添加的数据越来越多时,将其放入不同的集合中。

当表单有 X 个字段时,字段的数量在其生命周期内可能不会发生太大变化。因此,您应该将字段及其描述直接嵌入到表单对象中。

但是输入这些表单的答案数量会随着时间的推移而增加,这意味着这些应该被视为单独集合中的单独对象。

所以我建议你有两个集合,formsform_data

每个文档都嵌入了一个具有静态字段属性forms的子对象。fields

每个文档form_data都有一个带有相应表单的_id的字段,并嵌入一个子对象,该子对象使用与子对象field_data相同的键,并存储用户在该表单中所做的条目。fieldsforms

当您的用例需要频繁访问聚合数据时(例如,当您想在公共网站上发布最新统计数据时),您还可以将此信息存储formsform_data文件。MongoDB 通常建议您根据您的性能要求而不是数据的语义来定位您的数据库模式。

关于您的评论“这种情况下的所有数据都将是一致的”:请记住,MongoDB 不强制执行参照完整性。当应用程序删除或更改文档时,应用程序有责任修复其他文档中对它的任何过时引用。

于 2013-05-27T12:56:53.443 回答