Jam*_*mes 6 forms database-design webforms entity-attribute-value
在我参与的几个Web应用程序项目中,客户端要求能够创建自己的表单.问题出现在如何存储其表单定义,以及如何将用户输入的值存储到这些自定义表单中.
我已经看到它有两种方式:
假设客户端仅定义了多少个字段,以及与这些字段关联的标签; 我们可以找到一个涉及四个表的解决方案. FormDefinition
,FormFieldDefinition
,FormInstances
,FormFieldValues
.客户端对FormDefinition
和进行更改FormFieldDefinition
,并且Web应用程序使用该信息呈现HTML Web表单,网站访问者(最终用户)将在该表单上提交表单,其中FormInstances
创建新行并将值保存在FormFieldValues
表.
行中
FormDefinition
定义了表单,即form definition ID = 2, form title = 'Car Registration Form'
.行中FormFieldDefinition
定义表单的字段FormDefinition
,即field definition ID = 7, field label = 'Car Model', field type = 'varchar(50)'
.行FormInstance
是用户填写的每个表单的实例,即definition id = 2, date_entered = '2008-09-24'
.并且行FormFieldValues
是用户的条目,即field definition = 7, value = 'Tiburon'
.
不幸的是,这意味着value列FormFieldValues
必须是客户端可能在Web表单中指定的最大可能大小的char类型...并且当表单定义更改时,管理旧数据变得不确定.但用户条目是可查询的(我写了一个快速查询,列出了给定表单ID的用户条目,这类似于另一个数据透视问题).
使用四个表的另一种方法是将表单定义和用户表单条目序列化为XML(或YAML或类似的东西)并将其存储为文本.好处是表单在数据库中是人类可读的.缺点是解析XML会有更多的应用程序开销,从SQL的角度来看,数据库的可查询性要低得多.
我真正的问题是,这个数据库模型叫什么?(所以我可以谷歌这个问题.)但我会回答:哪个是更好的实现,还是有更好的(或同样好的)实现?
您所描述的内容通常称为“实体属性值”,有时被描述为“混合数据和元数据”。也就是说,属性(字段)的名称存储为字符串(数据)。
这会导致一系列复杂的问题,例如确保每个表单实例包含相同的字段集,或确保填写必填字段(相当于传统表中的 NOT NULL)。
您询问如何最好地使用关系数据库来做到这一点。在关系数据库中,元数据应该使用元数据。在这种情况下,这意味着为每个表单创建新表,并使用列作为表单字段。因此,您的表单定义只是表元数据,一个表单实例就是该表中的一行。如果您支持具有多值答案的表单(例如复选框),则还需要依赖表。
这可能看起来很昂贵或难以扩展。也许是真的。因此关系数据库可能不是完成这项工作的最佳工具。您提到了 XML 或 YAML 的可能性;基本上是某种可以临时定义的结构化文件格式。您应该为每个客户的表单定义一个 DTD,以便可以验证收集的每个表单。
编辑:如果您确实需要在应用程序中使用 EAV 的灵活性,那很好,通常在某些情况下违反规则是合理的。只需注意它需要的额外工作,并在您的开发计划中以及在扩展服务器以处理负载时对其进行规划。另请参阅我在 StackOverflow 上关于 EAV 的另一个答案。