What is the purpose of a database table that contains only primary and foreign keys?

荒凉一梦 提交于 2019-12-06 06:11:34

The ArtistTrack table is a junction table, a classic way of representing an M:N relationship. If you put a reference to the trackId in the Artist table, it would mean that each artist can have (at most) one track. Assuming this is not a database to manage one hit wonders, that would be wrong. If you put a reference to the artistId in the Track table, each track could be composed by (at most) one artist. If you want to allow collaborations in this database, that would also be wrong.

The solution is to have an ArtistTrack table, which, as you noted, just has references to relevant artists and tracks. E.g.:

-- Insert the track:
INSERT INTO Track VALUES (1, 'some track', 10, false, 1999);

-- Insert a couple of artists:
INSERT INTO Artist VALUES (1, 'Jay');
INSERT INTO Artist VALUES (2, 'Silent Bob');

-- Make them collaborate on this track
INSERT INTO ArtistTrack VALUES (1, 1, 1);
INSERT INTO ArtistTrack VALUES (2, 2, 1);

There are a number of ways to make any database, and there aren't universal rules for this type of thing. Depending on the needs of the application, and the type of database software you are using, you might store data differently.

That being said, if you were looking to use this table design for a traditional relational database, you would probably do it as the following for the Artist-Track situation you mentioned:

If you are entering a new Track with a new Artist you would first enter the new Track with its associated data (title, duration, live-performance, year) then enter the Artist with its associated data (name). Then, to associate the Artist with the Track you would add a row in the ArtistTrack table that contains the primary_id (random and unique key) and the foreign keys of artistID and trackID. The foreign keys in ArtistTrack are the primary keys of the Track and Artist you just entered.

I am guessing the reasoning that your tables are structured as you described was for allowing the potential of a track having many Artists, and an Artist having many Tracks. Because of the Many-To-Many relationship between those two entities, there is a bridging or association table (ArtistTrack) that allows easy lookup on Tracks and Artists to find the associations between them.

The tables you are wondering about, like "GenreTrack" or "AlbumTrack", are used to store how e.g. Tracks and Genres are combined respectively how any Track fits onto which album. This is a common way of storing so called n:m relationships in a normalised database. Let's look at GenreTrack as an example. Say Table "Genre" contains the following:

id     | name         |
    G1 | Rock         |
    G2 | Blues        |
    G3 | Pop          |

and "Tracks" looks like this:

  id | title                   | duration | live  | year
  T1 | "Pictures of You"       | 7:68     | FALSE | 2006
  T2 | "A Song for the Lovers  | 5:25     | FALSE | 1999

Now you want to be flexible with how you assign the genres to the tracks. Maybe you want to have "Song for the Lovers" beeing a "Pop" as well as a "Rock" song. Genres are debatable to some degree after all.

So, for that, a simple foreign key in the "Tracks" table won't help here. You need to store this separately. And this is where the "GenreTrack" table comes into play. It keeps all combinations of "Tracks" and "Genres". Entries in it could look like this:

id   | genreID  |trackID 
GT1  | G1       |   T1
GT2  | G3       |   T2 
GT3  | G1       |   T2

Now, you might be wondering, why this table got it's own "id" column. In fact, it is not necessary for making this a normalised table, since you could use "genreID" and "trackID" to form a compound primary key. However, some database frameworks apparently don't support compound keys and require a surrogate key for all tables, which is likely the reason for this "id" column here.

Selecting this data is straight forward:

SELECT t.title, t.year, g.name as genre_name
FROM 
     "Tracks" t
   left outer join "GenreTrack" gt
     on t.id = gt."trackID"
   left outer join "Genre" g
     on gt."genreID" = g."id";

Resulting in this :

 Title                   | Year    | Genre
 "Pictures of You"       | 2006    | Rock
 "A Song for the Lovers" | 1999    | Rock
 "A Song for the Lovers" | 1999    | Pop

Hope that gives you an idea on these m:n tables.

this is pretty straight forward. I've attached a sample data, please refer and let me know if it helps.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!