2009-07-15 206 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) 

等。

這樣你可以避免加載空字段;你的表不是那麼寬(總是可取的),並且你的記錄是隱式版本化的,因爲具有屬於你的基表中的記錄的記錄的表的列表告訴你原始表單具有哪些字段,因此什麼樣的表單是原來使用。