假設我有artist一張像這樣的桌子:
| ID | 姓名 |
|---|---|
| 1 | 約翰·科爾特蘭 |
| 2 | 斯普林斯汀 |
和一個song像這樣的表:
| ID | 標題 |
|---|---|
| 1 | 在雨中唱歌 |
| 2 | 含羞草 |
現在一個藝術家可以寫不止一首歌,而一首歌可以由不止一個藝術家寫。我們有一個多對多的關系。我們需要一個關聯表!
如何設計關聯表的主鍵?
一種方法是定義兩個外鍵的復合鍵,如下所示:
CREATE TABLE artist_song_map(
artist_id INTEGER,
song_id INTEGER,
PRIMARY KEY(artist_id, song_id),
FOREIGN KEY(artist_id) REFERENCES artist(id),
FOREIGN KEY(song_id) REFERENCES song(id)
)
另一種方法是使用合成主鍵,并對兩個外鍵的元組施加唯一約束:
CREATE TABLE artist_song_map(
id INTEGER PRIMARY KEY AUTOINCREMENT,
artist_id INTEGER,
song_id INTEGER,
UNIQUE(artist_id, song_id),
FOREIGN KEY(artist_id) REFERENCES artist(id),
FOREIGN KEY(song_id) REFERENCES song(id)
)
哪種設計選擇更好?
uj5u.com熱心網友回復:
除非您將表定義為WITHOUT ROWID兩個查詢將創建同一個表。
第二種方式的列id只添加了一個別名,該列rowid將以兩種方式中的任何一種方式創建。
由于這是一個橋表,您只需定義列artist_id和song_idas的組合UNIQUE。
如果您想使用其他表格(例如playlist表格)擴展您的設計,您將必須決定如何將其鏈接到現有表格:
- 如果其中沒有
id列,artist_song_map那么您將鏈接playlist到songandartist,就像您對artist_song_map. - 如果有一個
id列,artist_song_map那么您可以playlist直接鏈接到該列id。
我建議您不僅要根據這 3 個表(song和artist)artist_song_map,還要根據您計劃添加的表來做出決定。
uj5u.com熱心網友回復:
從邏輯上講,兩者的設計是相同的。但從管理方面來看,身份設計更有效。更少的磁盤碎片和未來的重新設計或維護會更容易。
uj5u.com熱心網友回復:
橋接表通常不需要 ID(auto_inCREMNT) 來識別行。
鏈接欄(外鍵)是重點,因為將藝術家鏈接到 8 或歌曲)
只有當您需要該橋的特殊屬性或者您想要參考該橋表的一行并且不想有兩個鏈接列時,您才會使用這樣的 ID 欄位,但正如我所說的,您通常不需要它
uj5u.com熱心網友回復:
雖然通常差異很小,但復合/復合外鍵設計聽起來更自然。單獨的主鍵與關聯的索引一起占用資料庫中的額外空間。此外,如果您使用復合主鍵,您可以將表宣告為 WITHOUT ROWID。根據官方檔案,“在某些情況下,一個 WITHOUT ROWID 表可以使用大約一半的磁盤空間,并且運行速度幾乎是兩倍”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/510181.html
上一篇:觸發器中的視窗函式lag()使用默認值而不是以前的值
下一篇:如何解鎖SQLite資料庫檔案?
