多字段表单的数据库设计

Database design for form with many fields

一个表单包含30-40个不同的字段(将来可能会添加更多,所以这必须是可能的)我需要找到一个好的数据结构将它们保存在数据库中(MS SQL服务器)。这些字段可以有不同的类型,例如复选框 (true/false)、选择(1 到 x 个可能的值可供选择)和文本字段。每种形式都可以通过操作号(字符串)和修订版(int)的组合键来识别。

这里有一个例子,想想更多这些类型的字段: Example form

我会这样尝试:

- table form
  - operation_number nvarchar(255) PK
  - revision int PK
  - created_at datetime
------------------------------------------------
This will be used for all true/false checkboxes:
- table checkbox_option
  - id int PK
  - form_operation_number nvarchar(255) FK (for form.operation_number)
  - form_revision int FK (for form.revision)
  - value bit
------------------------------------------------
This will be used for all text fields (see "Locations" and "Additional comments" in the example):
- table text_option
  - id int PK
  - form_operation_number nvarchar(255) FK (for form.operation_number)
  - form_revision int FK (for form.revision)
  - value varchar(max)
------------------------------------------------
This will be used for all selects:
- table select_option_name
  - id int PK
  - form_operation_number nvarchar(255) FK (for form.operation_number)
  - form_revision int FK (for form.revision)
  - name string (the text for the label, like "color" in the example)
------------------------------------------------
- table select_option_junction
  - select_option_name_id int PK FK (for select_option_name.id)
  - select_option_values_id int PK FK (for select_option_value.id)
------------------------------------------------
Table for all the options of a select field:
- table select_option_values
  - id int PK
  - value nvarchar(255)

这看起来是个不错的设计还是我忘记了一些重要的事情?也许你有更好的主意?谢谢。

id int PK

您会看到很多鼓励这种设计选择的建议。我反对。

首先深入一点。确定每列的。决定它与表格的关系。表单中可能出现不止一个值的任何列(例如,销售订单中的订单项目)进入另一个 table,通过外键与表单相关。

找出任何行中的哪些值唯一标识该行,即将它与所有其他行区分开来。那是一个自然键。通过使用自然键,您被迫了解数据的基数,并启用 DBMS 来执行它。

例如,您的颜色列将包含所有可能颜色的 table,一个 域 table。您可以使用颜色名称作为主键,因为没有两种颜色具有相同的名称。然后,在您的表单 table 中,您有一个带有颜色 table 外键的颜色列。如果用户以某种方式尝试插入 form-table 颜色不在颜色 table 中的行,DBMS 将拒绝它并违反外键。

如果 OTOH 您选择使用 id int PK 作为颜色的主键 table,没有什么可以阻止“蓝色”在table,可能是 id 7 和 17。为防止这种情况,您必须进行定义自然键所需的相同分析。添加代理项 id 键只会增加工作量。

自然键也更容易使用。 使用 id 主键,您的 form-table 在颜色列中只有一个不透明的数字。如果您使用自然键,您会看到“红色”而不是 11。

有人会警告您自然键可以更改。例如,一个人的名字可能会改变。这通常证明该列实际上不是自然键。更重要的是:如果你在数据中缺少一个可靠的例子,那么当 stable 数据改变的可能性发生时,任何设计努力都可能证明是不充分的(而且是错误的),如果它确实发生了。

有些情况下不存在或似乎不存在自然键。有时,与杂货或库存一样,无法区分的项目可以通过在数量栏中进行计数来计算。对于随时间变化(并随时间保留)的行,向键添加日期通常有效。

不过,有时您会向数据库中添加一些全新的内容,这些内容是任何人都懒得说出来的。 那是你需要发明一把钥匙的时候。