【问题标题】:What is the purpose of a database table that contains only primary and foreign keys?只包含主键和外键的数据库表的目的是什么?
【发布时间】:2017-05-07 10:39:42
【问题描述】:

我试图理解一个简单的音乐数据库设计。有些表只包含外键和主键。我不确定如何以及何时使用这些表或在其中插入什么。设计如下:

Track:
      id primary key
      title
      duration
      live-performance (true or false)
      year

Artist:
      id primary key
      name

ArtistTrack:
      id primary key
      artistID
      trackID

Album:
      id primary key
      title

AlbumTrack:
      id primary key
      albumID
      trackID
      track-number   

Genre:
     id primary key
     name

GenreTrack:
     id primary key
     genreID
     trackID          

例如,如果我在Track 表中插入一个曲目,在Artist 表中插入一个艺术家,那么我应该在ArtistTrack 表中插入什么?我假设ArtistTrack 表中的属性是与其各自表中的主键相同的数字?

我见过几个类似的设计,我就是不明白。我知道一个外键将表链接在一起。谁能给我一个关于如何使用这些表格的例子?

【问题讨论】:

  • 其中一些表是many to many 关系中的“链接表”。即专辑中有多个艺术家(艺术家到专辑链接表)。或者不止一个艺术家在一个轨道上。对于一首曲目,每个在该曲目上演奏的艺术家都会有一个条目。
  • 你可以不将数据存储在类似 SQL 的数据库中,即 NoSQL,你的架构看起来会非常不同。

标签: database database-design relational-database


【解决方案1】:

ArtistTrack 表是一个联结表,是表示 M:N 关系的经典方式。如果您在Artist 表中引用trackId,则意味着每个艺术家(最多)可以拥有一首曲目。假设这不是一个管理热门奇迹的数据库,那将是错误的。如果您在Track 表中引用artistId,则每首曲目可以由(最多)一位艺术家创作。如果你想在这个数据库中允许协作,那也是错误的。

解决方案是有一个ArtistTrack 表,正如您所指出的,它只包含对相关艺术家和曲目的引用。例如:

-- 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);

【讨论】:

    【解决方案2】:

    您想知道的表格,例如“GenreTrack”或“AlbumTrack”,用于存储例如Tracks 和 Genres 分别组合了任何 Track 如何适合哪个专辑。这是在规范化数据库中存储所谓的 n:m 关系的常用方法。 让我们以 GenreTrack 为例。 说表“流派”包含以下内容:

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

    “曲目”看起来像这样:

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

    现在,您希望灵活地为曲目分配流派。 也许你想让“情人之歌”成为“流行”和“摇滚”歌曲。毕竟流派在某种程度上是值得商榷的。

    因此,为此,“Tracks”表中的简单外键在这里无济于事。您需要单独存储它。这就是“流派跟踪”表发挥作用的地方。 它保留“曲目”和“流派”的所有组合。 其中的条目可能如下所示:

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

    现在,您可能想知道,为什么这个表有它自己的“id”列。事实上,没有必要将其设为规范化表,因为您可以使用“genreID”和“trackID”来形成复合主键。但是,某些数据库框架显然不支持复合键,并且需要为所有表提供代理键,这可能是此处出现“id”列的原因。

    选择这些数据很简单:

    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";
    

    结果:

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

    希望这能让您对这些 m:n 表有所了解。

    【讨论】:

    • 很好的解释。还有关于复合键。
    【解决方案3】:

    制作任何数据库的方法有很多种,但这类事物并没有通用的规则。根据应用程序的需求以及您使用的数据库软件的类型,您可能会以不同的方式存储数据。

    话虽如此,如果您希望将此表设计用于传统的关系数据库,您可能会针对您提到的 Artist-Track 情况进行以下操作:

    如果您要输入包含新艺术家的新曲目,您应首先输入新曲目及其相关数据(标题、持续时间、现场表演、年份),然后输入艺术家及其相关数据(名称)。然后,要将 Artist 与 Track 关联,您将在 ArtistTrack 表中添加一行,其中包含 primary_id(随机和唯一键)以及 ArtistID 和 trackID 的外键。 ArtistTrack 中的外键是刚刚输入的 Track 和 Artist 的主键。

    我猜您的表格按照您所描述的那样结构化的原因是允许一个具有许多艺术家的曲目的潜力,以及一个具有许多曲目的艺术家的潜力。由于这两个实体之间存在多对多关系,因此有一个桥接或关联表 (ArtistTrack),可以轻松查找 Tracks 和 Artists 以找到它们之间的关联。

    【讨论】:

      【解决方案4】:

      这很简单。 我附上了一个示例数据,如果有帮助,请参考并告诉我。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-08-20
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-10-24
        • 2012-12-15
        相关资源
        最近更新 更多