2009-07-15 201 views
4

数据库设计问题,你们都是。我有一个表单(如纸类),有几个数据入口点。这种形式已经发生了变化,预​​计会在几年内发生变化。它正在变成一个电脑应用程序,这样我们就可以停止浪费纸张。 (还有一些小问题,比如一个中央存储中的所有数据都可以被查询等等)。我想将所有表单数据存储在数据库中,并且对于这些更改非常不可知。数据库设计:将数据从纸质表格存储到数据库中

最初,我只是考虑每个字段是一个字符串 - 我有一个表是这样的:

FormId int (FK) 
FieldName nvarchar(64) 
FieldValue nvarchar(128) 

...类似的东西。实际上,3NFy中的FieldName位于另一个表中,与人工键相关联,因此字段名称不会在所有位置重复。

但是,我想扩展到数字和下拉数据。我只能将数字数据存储为字符串,但这似乎是一个相当糟糕的想法。与下拉菜单相同。

我可以停止使用表格,并且实际上使用主表格表格(上面引用的FormId表格)上的列,但这意味着在每个新项目出现时添加一列,而旧表格只会是空值。 (而且,除非我保存它,我也不会对该列创建时知道该字符串表上面,这是隐含的。)

我可以扩展表上面的东西,如:

FormId int (FK) 
FieldName nvarchar(64) 
FieldValueType int -- enum as to which of the columns below are valid (or just let nulls imply that) 
FieldValue nvarchar(128) 
FieldValueInt int 

组合必须位于OTLT(一个真正的查找表)中,我对此有所保留,但也许在这里需要?

有关StackOverflow的任何建议?我使用的是MSSQL,但这实际上是一个更普遍的问题。

回答

2

使用空值。正确的数据库设计是一个复杂的主题;你可能会做得很好,拿起一个很好的参考,并做一些研究(我收集this是一个关于这个主题的好书)。一般来说,听起来你可以从一个表格封装表单中的所有字段开始,然后将其通过规范化过程。是的,使用空值并且不要使用int来枚举哪些列设置为有效值;这正是空值。

2

对于每种数据类型,您都可以有单独的表。

I.e.使用表单ID获取整个表单,然后使用表单ID进行N方式连接,其中N表示您支持的不同数据类型的数量(+也许额外取决于您想要的信息 - 例如,下拉值可能存储在另一个表/你的字段名称查找/等)

但是,设计应该也许应该取决于你打算如何使用数据,这是你一无所知。这也取决于这些形式的变化速度有多快。 。 。

1

通过创建一个包含表单描述的表格,您实际上定义了一个元数据结构。这是令人生畏的。您需要大量适当的表格描述所需的基础设施。我认为你的数据库系统的供应商花了很多精力去做这些事情。

起初我以为 - 多好的主意!构建您自己的兼容感知表格描述系统!

但后来我想 - 我太愚蠢了,我自己做。必须有一个能够做到这一点的数据库系统。

所以我得出结论,不是数据库专家,在新的表单版本中为'新字段'定义适当的默认值。处理业务逻辑中的兼容性问题。

1

我强烈建议不要像你描述的“通用表”。

你基本上是在重新创建关系数据库,这不是一个好主意:查询和更新对于你的结构来说是非常痛苦的,而且你不能使用像外键和触发器这样更高级的功能,如果你需要他们。

只要为数据字段创建一个包含列的表,并且如果表单没有字段,则让它为空。

或者,甚至可能更好,有一个“基本表”(每个表单中都有一个字段),并为更新后的表单提供名称/版本号,并为此版本添加的新列创建一个新表,然后使用合成PK将这些新表连接到基表。

即:

base table: id(numeric,PK), name, birthday, town 

addresstable1: street, number, postal code, country, base_table_id (foreign key) 

addresstable2: po box no, po box code, base_table_id (FK) 

等。

这样你可以避免加载空字段;你的表不是那么宽(总是可取的),并且你的记录是隐式版本化的,因为具有属于你的基表中的记录的记录的表的列表告诉你原始表单具有哪些字段,因此什么样的表单是原来使用。