“其他 - 添加評論”的架構
許多使用者表單包含“其他 - 添加評論”選項,使用者可以在其中提供給定列表中未找到的項目。
換句話說,開發人員設置項目列表。使用者必須選擇一個項目或鍵入一個值。
例子:
- 您是怎麼知道我們的?{網路、電視、朋友、廣播、其他}
- 聯繫我們的原因?{銷售、技術支持、客戶服務、其他}
- 選擇您的列印機型號?
提議的架構:
model: model_id (PK), model_txt (UK), show (bool) request: request_id (PK), model_id (FK), {other non-relevant fields}
顯示模型,其中 show = 1
插入時,
- 如果從列表中選擇模型,請使用其 model_id
- 如果鍵入模型,
- 如果 model_txt 存在,則使用現有的 model_id
- 否則,插入新的 model_txt 並設置 show = 0
喜歡:
- 此解決方案避免了 NULL 值和空字元串
model_txt
無論使用者是否鍵入條目,所有請求的獲取都是相同的。不喜歡:
- 該
model
表將被僅與一個請求相關聯的項目污染。- 插入 model_txt 需要在 INSERT 命令之前執行一個額外的步驟。
如何改進此架構?
好問題。我對您的設計的反對意見是:您選擇將使用者輸入和預定義輸入視為同一事物(唯一的區別是 的值
show
)。但在我看來,它們不是。因為預定義的輸入是不同的選項,但不同的使用者輸入可能表示用同義詞、拼寫錯誤等編寫的相同想法,或者可能只是笑話或垃圾字元。您說這可以使您免於使用空字元串或 NULL。但我相信沒有值(自定義文本)是空字元串的有效用途。
沒有絕對正確或錯誤的方法,因為這取決於你之後如何使用這些數據,這就是你需要什麼樣的 SELECT 查詢。
因此,您的架構可能已經足夠好,無需任何改進。
這是我的替代方法,可以為您提供其他想法:
model: model_id (PK), model_txt (UK)
request: request_id (PK), model_id (FK), {other non-relevant fields}
request_model_other: id (PK), request_id (FK), other_txt
這樣,您就不會
model
因使用者的輸入而“污染”您的表格。它具有與您自己的“喜歡”相同的“喜歡”(您只需要一個額外的LEFT OUTER JOIN request_model_other
或類似的),但沒有不喜歡的。作為不喜歡的,它是另一個額外的表,在您的請求中必須考慮到。你甚至可以“合併”這兩個表:
request: request_id (PK), model_id (FK), model_other_txt, {other non-relevant fields}
如果您在約束中指定其中一個model_id
或model_other_txt
不是 NULL(但不能同時兩者)。然後,您顯然需要接受有很多 NULL 值。但同樣,我建議您考慮之後如何查詢這些數據以找到最適合您需求的模型。此外,“其他”案例多久會發生一次?它更像是1%?10%?90%?設計和優化也取決於此…