7

在我参与的几个 Web 应用程序项目中,客户要求能够创建自己的表单。问题出现在如何存储他们的表单定义,然后如何将用户输入的值存储到这些自定义表单中。

我已经看到它做了两种方式:

  1. 假设客户端只定义了多少个字段,以及与这些字段相关联的标签;我们可以得出一个涉及四个表的解决方案。 FormDefinition, FormFieldDefinition, FormInstances, FormFieldValues. FormDefinition客户端对and进行更改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)'。Rows inFormInstance是用户填写的每个表单的一个实例,即definition id = 2, date_entered = '2008-09-24'. 中的行FormFieldValues是用户的条目,即field definition = 7, value = 'Tiburon'.

    不幸的是,这意味着其中的值列FormFieldValues必须是您的客户可能在 Web 表单中指定的最大可能大小的 char 类型......并且当表单定义更改时,管理旧数据变得不确定。但是用户条目是可查询的(我写了一个快速查询,列出了给定表单 id 的用户条目,这类似于另一个 pivot question)。

  2. 使用四个表的替代方法是将表单定义和用户的表单条目序列化为 XML(或 YAML 或类似的东西)并将其存储为文本。好处是表格在数据库中是人类可读的。缺点是解析 XML 会产生更多的应用程序开销,并且从 SQL 的角度来看,数据库的可查询性会大大降低。

我真正的问题是,这个数据库模型叫什么?(所以我可以用谷歌搜索这个问题。)但我会选择一个答案:哪个是更好的实现,或者那里有更好的(或同样好的)实现?

4

4 回答 4

3

您所描述的内容通常被称为“实体-属性-值”,有时也被描述为“混合数据和元数据”。也就是说,属性(字段)的名称存储为字符串(数据)。

这会导致一系列复杂的问题,例如确保每个表单实例包含相同的字段集,或确保填写必填字段(相当于传统表中的 NOT NULL)。

您问如何最好地使用关系数据库来做到这一点。在关系数据库中,您应该使用元数据作为元数据。在这种情况下,这意味着为每个表单创建新表,并为表单字段使用列。因此,您的表单定义只是表元数据,一个表单实例是该表中的一行。如果您支持具有多值答案的表单(例如复选框),那么您也需要依赖表。

这可能看起来很昂贵或难以扩展。大概是真的。因此,关系数据库可能不是这项工作的最佳工具。您提到了 XML 或 YAML 的可能性;基本上是某种结构化的文件格式,您可以临时定义。您应该为每个客户的表单定义一个 DTD,以便可以验证收集的每个表单。

编辑:如果您真的需要在您的应用程序中使用 EAV 的灵活性,那很好,通常情况下有理由违反规则。请注意它需要的额外工作,并在您的开发计划中进行计划,并在您扩展服务器以处理负载时进行计划。另请参阅我在 StackOverflow 上关于 EAV的另一个答案。

于 2008-10-07T18:21:16.917 回答
2

这个数据库模型叫什么?

不知道实际上叫什么,但它与动态生成调查中使用的过程相同。如果您寻找任何用于生成调查应用程序的来源,您会发现相同的通用数据库模式以及类似的方法。

还可以查看表单构建器站点,例如http://wufoo.com/http://frevvo.com/以获取 UI 创意(如果您要使其基于 Web)。

于 2008-09-25T07:31:42.300 回答
1

还有第三个选项,您可以在其中创建表并在需要时添加列。这取决于创建了多少表格,但数据库可以轻松处理大量表格。因此,如果用户想要添加表格“汽车注册表格”,则添加表格“汽车注册表格”。对于表单上他们想要的每个字段,您可以让他们在一些基本类型之间进行选择,例如日期、整数和文本。选择文本时,它们必须从选择列表中输入最大长度,如果字段应该是VARCHAR或CLOB,则会为您提供信息。

这适用于 SQL Server,您可以在其中轻松添加和删除列。对于 DB2,这可能是个问题,因为没有实现 drop 列。对于 mysql 我不确定。

您仍然需要在两个单独的表中注册您的表单和其中的字段。

于 2008-09-25T07:45:53.700 回答
1

你可能想要实体关系模型

There are indeed GUI tools to create schema interactively from such models.

于 2008-11-04T20:58:20.120 回答