I'm making a database which includes artists, albums and songs. I have a table for artists (artists), for albums (albums) and for songs (songs). The album table has a foreign key from artists, the artist_id so I don't have to write the artists' names over and over again.
Now I want to add songs. I exported tag values of my albums to csv files. These I imported into mysql. That's the songs table, it includes: title, artist_name, album_name, time.
Now I want the songs to be linked to the corresponding album. So the column album_name from songs is album_name from albums. I don't know how to link them, as far as I know foreign keys need int. In albums there is album_id but that can't be included in songs, if I wanted to I would have to put them in manually, that's a lot of time.
I think you should refactor your songs table and replace artist_name with artist_id and album_name with ablum_id, which have a foreign key constraint on artists and albums tables respectively
Another way of looking at is:
the albums table is essentially a junction table between artists and songs. You could have called the table artists_songs to reflect the relationship.
In this case, your junction table should have both artist_id and song_id.
So the relationships will be
artists have many albums (or artists_songs), have many songs via albums
albums have many songs, belong to artists
songs belongs to albums, belongs to artists via albums
Related
I have the following album table:
album_id(PK)
album_name
artist_name
year
songs
My candidate keys are {id} and {album_name, artist_name}.
Now I am going to normalize the table till 3NF, and I would like to know the reason behind the data of artist_name column being redundant.
1NF
Goal: columns should be atomic.
Result:
album:
album_id(PK)
album_name
artist_name
year
song:
song_id(PK)
album_id(FK)
song_name
2NF
Goal: No partial functional dependencies of non-prime attributes (columns that don't exist in any candidate key) on candidate keys.
Solution: I couldn't find any partial functional dependencies.
3NF
Goal: No transitive functional dependencies of non-prime attributes on candidate keys.
Solution: I couldn't find any transitive dependencies.
Problem
Although the tables above seem normalized, there's the following problem: the data in the artist_name column is redundant. An artist with multiple albums will have their name stored multiple times, which we are against.
What am I missing?
i would create a table called artist and in there store the artist id and name and in the album table have a reference to that using a foreign key constraint. So where you would have artist name in album this would change to artist id. It wouldn't be a issue if you just have the name like you do now but if you have additional data that you would need to store for a artist then you would have to create the table anyway which would break the current design as you would have the name in the album table and the rest of the information in the artist table.
The main goal of normalization is to reduce redundancy. With the artist name being in the album table if you ever needed the name of a artist and additional artist info then you would have to include the album table and the artist table which wouldn't make sense and you wouldn't have any other columns besides name to link the tables together or duplicate the data in two places both the album and artist table which would violate the 1st normal form.
Also, with the name being in the album table your data would be split across two tables. The artists name isn't really a dependency on album but on the artist entity. This violates values stored in a column should be of the same domain principle of the 1st normal form.
I am currently learning database for an upcoming school semester, So I'm practicing with the books I currently have. I have books by multiple authors and authors with multiple books. Also books with multiple categories.
So I made three tables. A books table (with all the books information, including the author), an authors table (with the authors name, address, ect) and a categories table (since some books have multiple categories). Since some books have multiple authors and some authors have multiple books, I made a junction table called AuthorsBooks and filled it with information. By best practice, is it ok to NOT put authors with only one book in that (AuthorsBooks) table? Also, I created a BooksCategory junction table and put the books with multiple categories into that table. What would be the best way to link those two tables? By book title? Thanks.
In general your approach sounds correct with a few exceptions.
So I made three tables
Here's my count, based on your descriptions:
Authors
Books
Categories
AuthorsBooks
BooksCategories
A books table (with all the books information, including the author)
This is incorrect. At the point you realized you need AuthorsBooks, there is no reason to have author as part of the Books table. Any column(s) you used to implement that should be removed from Books.
By best practice, is it ok to NOT put authors with only one book in
that (AuthorsBooks) table?
Absolutely not. You created the right structure with AuthorsBooks. It supports any number of authors for a book.
Also, I created a BooksCategory junction table and put the books with
multiple categories into that table. What would be the best way to
link those two tables?
By Keys. Every table should have a primary key, and in your case the keys should be integers that get incremented with each new row.
Here's an outline of the table structure and standard naming.
Books
-----
id integer auto_increment primary key
title varchar(150)
Categories
----------
id integer auto_increment primary key
name varchar(60)
BooksCategories
---------------
books_id integer primary key (foreign key for Books.id)
categories_id integer primary key (foreign key for Categories.id)
My understanding with normalization after reading my book and going through a few youtube tutorials is that one of the important things is to not have repeating values. More specifically the primary key (ID) should not repeat.
So if I am working with some Tables in a Music/Concert database, then the following would be bad:
**CREATE TABLE Artists**
ArtistID INT *PRIMARY KEY*
ArtistName VARCHAR(30)
Albums
^Having Albums in the Artists table would be bad as there is One
Artist for Many Albums. Therefore the ArtistID would have to show up
in multiple rows [once for each album by the artist]
Question: Should a table like this have a foreign key that ties to another Table? The related table I would think about is obviously Albums.
Albums would have columns like:
CREATE Table Albums (
Album_ID INT NOT NULL AUTO_INCREMENT,
Album_Name VARCHAR(30),
Artist VARCHAR(30),
Release_Date DATETIME,
Genre or GenreID,
Primary Key (Album_ID) );
Question: But albums have songs. However I can't have Album ID as the Primary Key and then have all the songs with the repeating Primary Key of Album ID for each can I? Should I therefore keep the attribute 'Songs' out of the Album table?
Question: Should a table like this have a foreign key that ties to another Table? The related table I would think about is obviously Albums.
If the relationship between artist and album is one to many... (if the rules are that an "artist" can have zero, one or more "albums", and an "album" belongs to exactly one "artist")
We would implement that relationship by storing artist_id as a foreign key column on the album table.
Something like this:
artists:
artist
------
id 'PK'
name varchar
albums:
album
-----
id 'PK'
artist_id 'FK ref artist.id'
title
year
artwork
By storing a value in the artist_id column of album, that is a reference to a row in the artist table.
artist:
id name
---- --------
1 Kansas
2 Styx
album:
id artist_id name year
---- --------- -------------------- ----
432 1 Leftoverture 1976
435 1 Point of Know Return 1977
438 1 Monolith 1979
561 2 Grand Illusion 1977
Question: But albums have songs. ... Should I therefore keep the attribute 'Songs' out of the Album table?
Yes. If it's a one to many relationship between album and song, then store the album_id on the song table.
Like this:
songs:
song
----
id 'PK'
album_id 'FK ref album.id'
song_title
lyrics
song
id album_id song_title
---- -------- ------------------------
6777 435 Dust In The Wind
6801 438 People of the South Wind
5555 561 Come Sail Away
From a row in the song table, we can use the value stored in the album_id column to find the related album.
From a row in the album table, we can use the value stored in the artist_id column to find the related row in artist.
These examples are based on the simplistic one-to-many relationships that are described.
It's important that we get these rules for the relationships between the entities into a reasonable representation. We need to know if a relationship is one-to-many or many-to-many.
you need to read Database Systemsby Connolly & Begg - who will define clearly what makes data relational and how to define entities, and when to normalise data, but yes in answer to your question around whether you should use a foreign key in the songs table to link the artist to the song - remember this table will hold songs which means naturally the artist id would appear multiple times, and so on and so on research entities properly that will help.
How to structure tables for songs and playlists?
My thought was to create a table of playlists titles and id's then a playlists songs table that holds the songs unique id and the playlist which it belongs to. The other plan a new table for each playlist and store song information in each table for the playlist.
Would this be a good approach or is creating new tables bad for performance or any other reason?
How about something like this?
Songs:
id title length artist_id
Artists:
id name
Playlists:
id title user_id
Playlists_Songs:
playlist_id song_id
Users:
id name email
In terms of relational design, you need two tables for playlists, one holding the playlistname (key, playlistname), one for the actual playlists (key,playlistkey,trackid)
Table for tracks holding mp3 tag details (key, track title, artist key, album .... Etc)
Table for Artists (key, name, band). You can break it down further applying the principle that you should not duplicate data for instance holding a playlistname in more than one table. By creating views, you knit all this together
However, if you are using android, this database already exists.
I was wondering if there is some way to combine two indexes into third to make sort of serial number... For example:
If I want to create music database
I would start with table artists with
-artist_name
-artist_id (Primary key)
-....
Then table albums with
-album_name
-album_id (P.k.)
-...
And then table songs with
-song_title
-song_id
Let's say artist would be X with artist_id - 12345
Then album Y with album_id - 678
And I want song_id to be 12345.678.xxx (dots only for visualization of the idea, length of artist_id and album_id would be constant)
My question is. Is something like possible?
Because I have a feeling that this would perform much more better search through database.
Not only that in my song_id I have full information of artist and album (I don't need to use foreign keys than), it should speed up any query about songs from the same album or other albums of the same artist. All information in one index and it needs only some kind of extraction.
Or maybe its just mine minimal knowledge about MySQL? :)
Keep artist_id and album_id as separate columns in the songs table and include proper foreign key relationships and indexes. This will give you the best combination of data integrity and query performance.