除非你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