列表和項目列表,而不是每個“列表”一個表?
我正在為客戶處理的一個 sql 數據庫是用一種不尋常的結構創建的。
例如,不要為以下各項設置一個表:
- 國家,
- 狀態,
- 城市,
- 單位(英寸、米、英里/小時)、
他們只有兩張桌子:
- 一個用於列表 ID(欄位:列表索引和列表名稱)。記錄前:城市,單位
- 一個用於給定列表中的項目(欄位:項目索引、列表項的描述和引用上述相關列表索引的 fk)。記錄前:km/h、亞特蘭大、英里、巴黎
listitem 表中 id 的序列是這樣組織的,以便在一定程度上將 listitem 中不同組的項目分開,以防需要在列表中添加新項目:
- Unit 的 Seq 可能從 20000 開始
- 城市序列可能從 30000 開始
因此,如果需要添加 10 個新單元,則索引可以與其他已創建的單元保持組合,而不會溢出到其他項目(如城市)中。應用層處理每組項目的序列範圍。
他們在列表表中有 30 多個這樣的列表,並且在項目表中有數千個項目,每個項目都與列表 ID 相關。
我認為這是沒有意義的,原因有很多。但他們認為這很有效,因為“我們只有 2 張桌子而不是 30 張桌子”。他們還認為這是一種新穎且有點典型的工作方式。我知道這在技術上是可行的,但我預計這兩個表的實現會出現不必要的和多重問題。
我的問題:做上述事情是典型的還是公認的做法?
這是一種已知的模式,但不是一個好的模式,也不是新奇的。雖然可以使應用程序以這種方式執行,但您會錯過很多好處。
首先,外鍵。不能聲明對列表表的引用“只能聲明 10,000 範圍內的 ID”。因此,適當的參照完整性消失了。沒有什麼可以阻止重達 10 個倫敦的產品和被著色為法蘭克福的產品。
第二,數據類型。所有列表值數據類型必須是最小公分母。在實踐中,這意味著 Unicode。同樣,沒有什麼可以阻止車輛的乘客人數為 {1, 2, 3, Tuesday} 之一。
類似地,長度必須是可以想像的最大長度,而不僅僅是已知的最長。這會在儲存、記憶體消耗等方面產生成本。
第三,您最終可能只有一個表,但該表中仍然有 30 多種實體類型。這些並沒有消失。這增加了不必要的認知負擔。與其在名為 Cities 的表中查找城市,不如記住它在名為 Lists 的表中,介於 10,000 和 15,000 之間(或者是 20,000 到 30,000?)。
第四,加入失去自我證明。代替
... Data as d inner join Cities as c on c.CityId = d.CityId inner join Units as u on u.UnitId = d.UnitId
相反,我們有
... Data as d inner join Lists as l1 on l1.ListId = d.CityId inner join Lists as l2 on l2.ListId = d.UnitId
我知道我更喜歡哪個。
第五,對於單獨的表,每個表的鍵可能是 256 個值的 1 字節整數。當我打賭這將是一個 4 字節的整數時。當然,總體上不是一大堆字節。但是為什麼要減少表數而不是字節數呢?
我將在這裡停下來,以這個觀察結束。沒有一個名副其實的 DBMS 會關心其目錄中少 30 個表的情況。它對執行時間的影響絕對為零,但會在未來幾年困擾維護。