邏輯數據庫設計 - 多列屬性(多列轉行)

  假設有一個要開發一個試題系統,全是不定項選擇題。一道題可能有2,3,4...個答案,數據應如何設計呢?本處旨在說明問題所在,例如同類問題還有存儲電話,一我的可能有多個號碼等等。javascript

1、存儲多值屬性

  反模式:建立多個列。html

  咱們知道每列最好只存儲一個值,所以先看以下設計:java

複製代碼
  CREATE TABLE Question(
      QuestionId int   PK,
      QuestionBody nvarchar(500),
      Answer1  nvarchar(500),
      Answer2  nvarchar(500),
      Answer3  nvarchar(500),
      Answer4  nvarchar(500)
  )
複製代碼

  相似上面的設計,假設答案只有兩個,那麼後面的兩個Answer3,Answer4就爲NULL,展現表以下:git

  

  這是很傳統的屬性設計,致使即便如今很簡單的任務也變得很簡單了!數據庫

  一、查詢數據數據庫設計

  假設有一道題的答案出錯了,可是你只記得答案。post

SELECT * FROM Question WHERE 
    Answer1 = '豬有4條腿'
    OR Answer2 = '豬有4條腿'
    OR Answer3 = '豬有4條腿'
    OR Answer4 = '豬有4條腿'

  顯示結果以下:this

  

  假如,另外也有一道題目,也有一個答案豬有3條腿,那麼你要查得這條數據,就須要這樣:spa

SELECT * FROM Question WHERE 
    (Answer1 = '豬有4條腿' OR Answer2 = '豬有4條腿' OR Answer3 = '豬有4條腿' OR Answer4 = '豬有4條腿')
    AND
    (Answer1 = '豬有3條腿' OR Answer2 = '豬有3條腿' OR Answer3 = '豬有3條腿' OR Answer4 = '豬有3條腿')

  怎麼樣又長又臭吧!不怕,哥安慰下你,其實有簡單點的方法:設計

  SELECT * FROM Question WHERE 
      '豬有3條腿' IN (Answer1,Answer2,Answer3,Answer4)
      AND
      '豬有4條腿' IN (Answer1,Answer2,Answer3,Answer4)

  怎麼樣短了不少吧,相信你也仍是不會賣賬。

  二、添加、更新以及刪除值

  在以上設計中,假設我要刪除答案'豬有3條腿'的SQL語句怎麼寫呢?你們被考到了吧。

  UPDATE Question
      SET Answer1 = NULLIF(Answer1,'豬有3條腿'),
          Answer2 = NULLIF(Answer2,'豬有3條腿'),
          Answer3 = NULLIF(Answer3,'豬有3條腿'),
          Answer4 = NULLIF(Answer4,'豬有5條腿')
  WHERE QuestionId = 2

  添加一個答案,更新一個答案都有點難寫, 有興趣的朋友能夠本身敲敲。

  三、確保惟一性

  如何確保同一個值不出如今多個列中,即有可能你並不想一道題中有兩個答案是同樣的。咱們很難阻止重複的答案出現,由於Unique只能用於行。

  四、值在不斷增加

  當咱們有一道題有5個答案的時候,悲劇,你要更改表結構了。

  以上種種問題說明,以上設計根本不堪一擊。

2、解決方案 - 從屬表

  問題的根源在於:存儲一個具備多個值的屬性。對於以上設計,若是每道題都規定是4個答案,以上設計是能夠用的。問題在於,答案個數不肯定。

  所以,咱們須要建立一個從屬表,將不肯定個數的值提取出來做爲行存儲,而不是列。

  整體設計以下:

複製代碼
CREATE TABLE Question(
    QuestionId    int    PK,
    QuestionBody Body nvarchar(500)
)

CREATE TABLE Answer(
    AnswerId    int    PK,
    AnswerBody    nvarchar(500),
    QuestionId    int,
    FOREIGN KEY(QuestionId) REFERENCES Question(QuestionId)
)
複製代碼

  對於以上設計,多少個答案都沒問題了,並且增刪查改都簡單了不止一個檔次。

  其實,只不過是一個一對多的關係。並且這個問題很容易一眼就看出,不過變種問題你卻未必會條件反應式地提出同樣從屬表。

 

 
 
 
0
0
 
(請您對文章作出評價)
 
« 上一篇: IBatis.Net 錶鏈接查詢(五)
» 下一篇: 邏輯數據庫設計 - 元數據分裂(分區表)
相關文章
相關標籤/搜索