1

I'm generally a front end developer (HTML/CSS etc) but currently getting my chops stuck into some back end development for a challenge. Please bear in mind I've only been doing this back-end thing for a few weeks so my terminology / logic is in its infancy... Go easy ;)

As a starting point, I'm building a thing in PHP & MySQL so I can catalogue my vinyl collection. It's a really simple form that takes artist, title, label etc and stores that into a MySQL db. I also want to implement tags for each record so one track might be tagged 'House | funky | vocal' whilst another would be tagged 'dubstep | MC | Bass' or something like that.

I can't store these tags as an array in MySQL so I understand that I need to insert them as a comma separated value and then when I want to work with these at a front-end level, I need to pull the CSV out of the database, EXPLODE that value and display each element as a separate list element.

That part I understand. But how do I go about adding additional tags? I can't seem to find a definitive answer (maybe I'm searching the wrong thing?) but so far, all I can work out is that I'd have to take the current database value of 'tags' from the db and store that as a variable. Delete the 'tags' value from the db, append a new tag to the variable and then store the new variable back into the database.

Surely there's an easier way though?

4

1 回答 1

2

您应该研究关系表和外键的概念。您最好将标签分解成自己的表格,如下所示:

专辑表

album_id  album_artist    album_title
---------------------------------------------------
1         Nirvana         In Utero
2         Noisia          Split the Atom

标签表

album_id  tag
--------------------------------------------------
1         Rock
1         Grunge
1         Alternative
2         Dubstep
2         Drum & Bass
2         Experimental

然后,您可以使用 GROUP CONCAT 将它们重新加入逗号分隔列表

SELECT       a.album_artist
            ,a.album_title
            ,GROUP_CONCAT(b.tag) AS tags
FROM        Album a
JOIN        Tags b
USING       (album_id)
WHERE       album_id = xxx

结果:

album_artist    album_title       tags
---------------------------------------------------
Nirvana         In Utero          Rock, Grunge, Alternative
Noisia          Split the Atom    Dubstep, Drum & Bass, Experimental

您可以进一步将数据分解为艺术家表,其中album_artist 名称由艺术家表中的艺术家ID 替换,标签名称被分隔到另一个表中,标签名称被替换为tag_ids ...

请注意,这GROUP_CONCAT是特定于 MySQL 的……很确定 SQL SERVER 2005 及更高版本有类似的东西,但我不记得他们怎么称呼它。也是USING (col_name)MySQL 特有的,它只是编写 ON 子句的一种更简单的方法, ON a.album_id = b.album_id 并且只能在连接列具有相同名称时使用。我只是更喜欢它USINGON因为它更短并且使复杂的查询更具可读性。

https://en.wikipedia.org/wiki/Database_normalization

编辑 根据您的评论,如果您将标签拆分到自己的表格中,这就是它的样子。我又添加了 2 个条目来显示值重复 - 请注意 Rock、Dubstep 和 Experimental 的使用次数超过 1 次,但它们的文本值仅列出一次...

Album table:

album_id  album_artist        album_title
---------------------------------------------------
1     Nirvana                 In Utero
2     Noisia                  Split the Atom
3     Nero                    Welcome Reality
4     Pink Floyd              The Wall

Tags table:

tag_id    tag
--------------------------------------------------
1         Rock
2         Grunge
3         Alternative
4         Dubstep
5         Drum & Bass
6         Experimental

Album_Tags table:

album_id  tag_id
--------------------------------------------------
1         1
1         2
1         3
2         4
2         5
2         6
3         4
4         1
4         6

询问:

SELECT       a.album_artist
            ,a.album_title
            GROUP CONCAT(c.tag) AS tags
FROM        Album a
JOIN        Tags b
USING       (album_id)
JOIN        Album_Tags c
USING       (tag_id)
WHERE       album_id = xxx
ORDER BY    album_title ASC

结果:

album_artist  album_title         tags
---------------------------------------------------
Nirvana       In Utero            Rock, Grunge, Alternative
Noisia        Split the Atom      Dubstep, Drum & Bass, Experimental
Pink Floyd    The Wall            Rock, Experimental
Nero          Welcome Reality     Dubstep
于 2013-05-06T07:17:31.833 回答