Mysql
在關係數據庫中為可能的空值創建另一個表會更好嗎?
我正在設計一個在MySQL中使用的關係數據庫。我有下一種情況:在一個表中,大多數情況下的欄位是
NULL
. 欄位將如下所示:Table name: tabla Fields: idtabla not null, text (varchar(n)) not null, image (mediumblob) {this can be null}
疑問:最好創建另一個表,並在需要使用圖像時查詢新表?為什麼您的解決方案更適合設計?MySQL的時間響應,易於查詢等?
您在這裡觸及了一個幾乎是哲學的論點:是否應該允許 NULLable 值,因為它們違反了模型關係數據庫源自的“封閉世界”假設(參見http://en.wikipedia.org/wiki的相關部分/Null_(SQL)和這裡的許多其他問題,例如為什麼我們不應該允許 NULL?為避免未知值將可能未知(或根本不適用於所有情況)的屬性拆分為它們自己的關係(表),這樣您就沒有未知的值,而是如果值未知,則它根本不存在. 雖然這滿足了理論,但也有一些實際意義使其不太理想:
- 在
JOIN
大多數 RDBMS 中,操作不是免費的,在額外表中搜尋屬性會增加引擎為滿足您的查詢而需要做的工作。- 如果屬性的存在不是相互依賴的(即每個屬性都可以是未知的,而與其他屬性無關),那麼為了得出結論,您有時最終需要為每個屬性創建一個表。
- 額外的連接會增加查詢的複雜性並降低可維護性。
- 更新在某些地方也變得不那麼直覺:空白屬性現在變成了一個 DELETE 操作,更新一個可能是 an
INSERT
或 anUPDATE
。當然,在某些情況下,第一點是相反的,打破屬性會提高效率:
- 大多數 RBDMS 使用基於頁面的儲存,並且從核心數據中分離可選資訊意味著您可以在給定頁面中容納更多核心數據行。根據您的數據大小、RAM 和儲存基礎架構,這對於減少某些大型查詢所需的 IO 量可能非常重要(但通常不是:盡量不要在這一點上“過度優化”,至少在沒有執行良好基準的情況下)以確保情況正在改善而不是惡化)。
這當然是假設您的查詢經過設計,因此它們只獲取所需的內容,因此引擎無論如何都不需要關心額外資訊中的繪圖。
- 同樣,如果您只更新
INSERT
or中的核心資訊UPDATE
,並且您在這些額外屬性周圍有約束或觸發器,則可能會在每次行更改時避免此處理。您的範例看起來像是在儲存圖像(或至少在 blob 類型列中儲存大量數據。這裡有兩個額外的注意事項:
- 大多數數據庫引擎無論如何都會“離頁”儲存大數據,所以如果你避免的話,無論如何
SELECT *
你都會“免費”獲得每頁行數的獎勵。- 將它們移動到別處是否允許您在多個實體之間共享大數據,而不是多次儲存同一個 blob,或者資訊(如果存在)對於給定行是否唯一?
**tl; dr:**所以恐怕沒有硬性和快速的答案。我的建議是做任何最適合你的數據概念模型的事情,因此你需要更少的思考來維護。這通常但並非總是意味著使用可空列而不是單獨的表。除非您的數據確實非常龐大,否則性能差異將可以忽略不計。