除非你denormalized(2)流派到三列出於性能的考慮,應該有相關的歌曲和流派一個單獨的表:
CREATE TABLE SongGenres (
song INT NOT NULL REFERENCES Songs (id) ON DELETE CASCADE,
genre VARCHAR(32) NOT NULL,
UNIQUE INDEX (song, genre),
INDEX genres (genre) -- improves performance for getting genre names
) Engine=InnoDB;
這摒棄了要求的(「十字街藍調「可以在」藍調「和」三角洲藍調「下提交,但這就是關於它)和人工限制(A3的鄉村酸屋福音浮現在腦海中)每首歌的三種流派。如果您有一套有限的流派,您可能需要製作流派專欄enumerated。該SongGenres表進行了簡化讓所有流派:
SELECT UNIQUE genre FROM SongGenres;
另外,還可以進一步規範和創造流派單獨的表:
CREATE TABLE Genres (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(32) NOT NULL,
UNIQUE INDEX (name)
) Engine=InnoDB;
CREATE TABLE SongGenres (
song INT NOT NULL REFERENCES Songs (id) ON DELETE CASCADE,
genre INT NOT NULL REFERENCES Genres (id) ON DELETE RESTRICT,
UNIQUE INDEX (song, genre)
) Engine=InnoDB;
簡化了獲取所有種類名甚至更多(儘管這只是一個第二個優點):
SELECT name FROM Genres;
到流派表的主要優點是數據正確性:如果有人拼錯流派,它不會被在流派發現噸能夠。一個潛在的缺點是它將有效的流派限制在表格中的那些流派。當然,給予SongGenres上擁有INSERT權限的用戶帳號是有意義的,所以這個限制並不嚴重。一旦你開始添加新的流派,你將面臨與沒有流派表的錯誤相同的問題:打字錯誤。而不是添加流派表中找不到的新流派,查找類似的流派(例如,使用Levenshtein distance或SOUNDS LIKE
),如果找到任何流派,請詢問用戶是否要用發現的流派或保留原始類型(並將其添加到流派列表中)。
這裏的數據是什麼樣子在第一種情況下(兩個表,Songs
和SongGenres
):
mysql> SELECT * FROM Songs;
+----+---------------------+--------+----
| id | title | artist | ...
+----+---------------------+--------+----
| 1 | Cross Road Blues | ...
| 2 | Peace In the Valley | ...
+----+---------------------+--------+----
2 rows in set (0.00 sec)
mysql> SELECT * FROM SongGenres;
+------+-------------+
| song | genre |
+------+-------------+
| 2 | acid |
| 1 | blues |
| 2 | country |
| 1 | delta blues |
| 2 | gospel |
| 2 | house |
| 2 | techno |
+------+-------------+
7 rows in set (0.00 sec)
mysql> SELECT s.title, sg.genre FROM Songs AS s JOIN SongGenres AS sg ON s.id=sg.song;
+---------------------+-------------+
| title | genre |
+---------------------+-------------+
| Cross Road Blues | blues |
| Cross Road Blues | delta blues |
| Peace In the Valley | acid |
| Peace In the Valley | country |
| Peace In the Valley | gospel |
| Peace In the Valley | house |
| Peace In the Valley | techno |
+---------------------+-------------+
7 rows in set (0.00 sec)
設有一個獨立的流派表,在歌曲中的數據會看起來一樣,但在其他我們會有類似的表格:
mysql> SELECT * FROM Genres;
+----+-------------+
| id | name |
+----+-------------+
| 1 | acid |
| 2 | blues |
| 3 | classical |
| 4 | country |
| 5 | delta blues |
| 6 | folk |
| 7 | gospel |
| 8 | hip-hop |
| 9 | house |
...
| 18 | techno |
+----+-------------+
18 rows in set (0.00 sec)
mysql> SELECT * FROM SongGenres;
+------+-------+
| song | genre |
+------+-------+
| 1 | 2 |
| 1 | 5 |
| 2 | 1 |
| 2 | 4 |
| 2 | 7 |
| 2 | 9 |
| 2 | 18 |
+------+-------+
7 rows in set (0.00 sec)
mysql> SELECT s.title, g.name AS genre
-> FROM Songs AS s
-> JOIN SongGenres AS sg ON s.id=sg.song
-> JOIN Genres AS g ON sg.genre=g.id;
+---------------------+-------------+
| title | genre |
+---------------------+-------------+
| Cross Road Blues | blues |
| Cross Road Blues | delta blues |
| Peace In the Valley | acid |
| Peace In the Valley | country |
| Peace In the Valley | gospel |
| Peace In the Valley | house |
| Peace In the Valley | techno |
+---------------------+-------------+
7 rows in set (0.00 sec)
當他們從MySql進來時數據看起來像什麼?它是一個數組嗎? – Jon 2010-11-30 17:49:50