Reputation: 13
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?
Upvotes: 1
Views: 2148
Reputation: 4411
You should study up on the concept of relation tables and foreign keys. You would be better breaking up the tags into its own table, something like this:
Album table
album_id album_artist album_title --------------------------------------------------- 1 Nirvana In Utero 2 Noisia Split the Atom
Tags table
album_id tag -------------------------------------------------- 1 Rock 1 Grunge 1 Alternative 2 Dubstep 2 Drum & Bass 2 Experimental
Then you can join them back into a comma delimited list using 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
results:
album_artist album_title tags --------------------------------------------------- Nirvana In Utero Rock, Grunge, Alternative Noisia Split the Atom Dubstep, Drum & Bass, Experimental
You could further break up the data into an artists table, where the album_artist name is replaced by the artist id in the artists table, and the tag names are separated into another table and the tag names are replaced with the tag_ids...
Note that GROUP_CONCAT
is specific to MySQL... Pretty sure SQL SERVER 2005 and later has something similar but I don't remember what they call it. Also USING (col_name)
is MySQL specific, its just an easier way of writing an ON clause like ON a.album_id = b.album_id
and can only be used when the joining columns have the same name. I just prefer USING
to ON
because its shorter and makes complicated queries more readable.
https://en.wikipedia.org/wiki/Database_normalization
Edit Per your comment, here is what it would look like if you broke tags off into its own table. I added 2 more entries to show value repetition - notice how Rock, Dubstep and Experimental are used more than 1 time but their text values are only listed once...
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
Query:
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
Results:
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
Upvotes: 2