2011-05-17 62 views
0

我還沒有設計過一段時間的數據庫,現在我對我的設計沒有太大的信心。我基本上在數據庫中有三個表格,表示各種歷史記錄。我必須改變這個系統,以便每次添加一個記錄(例如某些事情變成歷史)時,可能需要來自用戶的一些輸入。有時他們只會有一個簡單的問題,有時候他們會被要求提供五種不同的信息,並且這些信息需要由最終用戶通過管理前端進行靈活管理。所以我打算有一個問題表和答案表,用複合表把它們和其他三個表聯繫起來。我在設計答案表時很掙扎,因爲每個問題都可能需要各種答案。一些響應將是通過外鍵綁定到另一個數據庫的下拉選擇。其他可能是文本輸入,日期或是/否答案。現在,我有一個涵蓋所有類型的一系列可空字段的答案的回答表...數據庫設計:靈活的Q&A存儲

+----------------------------+ 
| Answer      | 
+----------------------------+ 
| Id (int)     | 
| QuestionId (int)   | 
| ForeignKeyId1* (int)  | 
| ForeignKeyId2* (int)  | 
| ForeignKeyId3* (int)  | 
| Number* (bigint)   | 
| DateField* (date)   | 
| Text* (varchar 500)  | 
| YesNo* (bit)    | 
+----------------------------+ 
    *Nullable 

旁註:這個問題表關係到QuestionType這將決定(在應用程序中)如何驗證用戶輸入。輸入被存儲在應答記錄的適當的可空字段中,其他字段被清除。我認爲這會比沒有數據完整性的catch all varchar answer字段更好。

這是一個糟糕的設計?有什麼可以讓它變得更好?

回答

1

從你所描述的,你的解決方案看起來應該很好。我已經完成了類似的設置,其中有一些列設置了記錄特定類型數據的列,允許其他字段爲空。雖然我不確定你的ForeignKeyID字段是什麼,但看起來不錯:\

+0

的ForeignKeyId字段的答案,用戶會從下拉列表挑選。他們綁在其他桌子上。感謝您的反饋:) – 2011-05-18 19:32:45

+0

好的。不是要告訴你想要做什麼,但是你是否考慮製作另一個答案ID和問題ID表。這樣你就可以得到儘可能多的有效答案。目前,如果您想爲任何問題添加另一個有效答案,就會遇到問題。只是一個建議:)希望一切順利。 – 2011-05-18 19:41:46

+0

已經有這樣的實施,但它不是真的與手頭上的問題相關;) – 2011-05-18 21:40:11

1

對不同的數據類型有不同的字段是可以的,因爲有多個外鍵。這種設計將盡可能多的數據域完整性引入DBMS。這在哲學上是一條很好的路,因爲大多數人會告訴你,讓DMBS爲你做這項工作將會節省你編寫和維護代碼的時間。我大部分時間都是那些人中的一員。

還有另一種方式來從可維護性方面來看待這個問題。就目前而言,如果添加新類型的數據類型(例如浮點數或GUID),則必須返回並修改ANSWER表的結構。同樣,如果您創建另一個需要來自新查找表的答案的問題類型,則必須返回並添加另一個FK字段。

你可以改變你回答表看使用包羅萬象的做法,以便它看起來更像是這樣的:

ANSWER 
(Id (int) 
, QuestionId (int) 
, Part (int) 
, Value (nvarchar 1000) 
) 

如果我理解正確你的問題,一個問題可以有一個多部分答案。假設單個問題可能有多個答案,並且您的問題控制表知道哪個部分是哪個部分,那麼您可以使用部分字段來區分這些部分。如果每個問題只有零個或一個答案,那麼您不需要答案表,只需將問題的答案添加進去即可。

那麼,爲什麼你想放棄讓數據庫強制數據域的完整性呢?以下是相對利弊:

多個獨立答田優點:

  • DBMS不會讓你把錯誤的數據類型到字段,所以你不需要寫或存儲數據之前調用任何數據域完整性功能(除非你想捕獲這些錯誤,GUI級)
  • 有沒有關於如何解釋答案的內容混淆(例如,它是一個月,這是一天在這個日期的答案...)
一個兩難的210個

所有優點回答字段:

  • 你不必編寫額外的代碼來 看問題類型,找出 在回答表哪一列於 閱讀任何給定類型的問題。
  • 您不必在每次添加新的查找表 或應答數據類型的時間來改變你的 數據庫模式/物理數據庫 人口。

在這兩種情況下,你必須寫一些代碼來處理你存儲語義不同的答案,在一個數據存儲多個問題的事實。你必須決定你想要寫,即計算出往哪裏放,並找到每個類型的答案,或者說數字如何使用通用的表示來存儲和解釋不同的數據類型的種類,種類(即串哪種類型的額外代碼)。

鑑於修改一個包含數據的表是一種痛苦,並且考慮到大多數編程語言都內置了相當健壯的.ToString()/ .TryParse()類型的功能,我傾向於使用catch-all如果我的主要關切是可維護性的話。

+0

非常感謝您提供這個答案! – 2011-05-23 19:49:34