如何使单个列引用多个表

时间:2014-03-03 20:49:19

标签: mysql sql database-design

我这里有4张桌子,他们的关系如下: enter image description here

对于'band'表,我有4列:id,band_name,first_name,last_name。 (first_name和last_name引用“独立艺术家”表中的列。)

对于“独立艺术家”,我有3列:id,first_name,last_name。

对于'act'表,我有3列:id,表演者,音乐。对于调香师来说,我想参考乐队和独立艺术家表。

对于'music'表,我有3列:id,song_name,release_year。

我还预测未来的变化,例如,如果乐队中的团队成员想要更改他的姓氏,它将影响“乐队”和“独立艺术家”表。

直觉上我认为我的解决方案并不好,任何人都可以为表提供更好的设计吗?感谢。

5 个答案:

答案 0 :(得分:3)

这是我的建议:

乐队表:

  • band_id PK
  • band_name

艺术家表:

  • artist_id PK
  • 如first_name
  • 姓氏

Band_members表:

  • band_id FK
  • artist_id FK

使徒行传表:

  • act_id PK
  • band_id FK

音乐表:

  • music_id PK
  • SONG_NAME
  • RELEASE_YEAR

Act_Contents表:

  • act_id FK
  • music_id FK

不需要单独的Independent Artists表。只需将他们视为只有一名成员的乐队。并且您应该始终使用ID作为外键,因此如果属性发生更改,您不必担心更新引用;你只需在一个地方改变它,参考不受影响。

答案 1 :(得分:2)

您可能希望在bandartist之间建立一对多关系,其中乐队可以引用一位或多位艺术家(通过ID或艺术家)。这样,名字和姓氏就会保留在artist表格中,并且不会在band表格中重复。

至于您遇到的其他问题 - 您无法在关系中引用多个外表的列。您必须通过在Act表中创建两列,一个引用band和一个引用artist的列来建模,并添加一个只有一个可能非空的约束或者别的什么。

那就是说,你可能希望take a look at MusicBrainz获得灵感。我过去曾使用过该数据库,该项目正在由许多聪明人开发,他们已经在模型上工作了一段时间。

答案 2 :(得分:1)

你很难过 - 你需要performeract相关联,而不是bandartist。我的意思是你需要一个关于链接到act对象的对象的抽象。然后,performer将首先链接到band对象,然后再链接到artist。您需要语法确定表演者是乐队还是独立艺术家,具体取决于与两个对象之一的当前链接。  当然,你需要乐队和艺术家之间的多对多关系。 像这样:

band(id PK, name)
artist(id PK, first_name, last_name)
band_artists(band_id, artist_id)
performer(id PK, band_id, artist_id)
act(id PK, performer_id, music_id)
music(id, song_name, release_year)

我不建议你只为乐队和艺术家使用一个对象,因为它们有不同的含义和自己的生命。在将来,您可能希望为艺术家添加一些物理特征,例如与坏人无关等等。

当表演者是乐队或艺术家时,很容易知道。在第一种情况下,band_id字段将具有非NULL值。在第二个中,band_id中的NULL值和artist_id字段中的非NULL值。

如果您需要检索有关歌曲的表演者的信息,例如您可以通过以下方式进行:

SELECT 
    music.song_name, 
    performer.id as performer_id, 
    group.name as group_name,
    artist.first_name,
    artist.second_name
FROM music 
    LEFT JOIN act on music.id = act.music_id
    LEFT JOIN performer on act.performer_id = performer.id
    LEFT JOIN band on performer.band_id = band.id
    LEFT JOIN artist on performer.artist_id = artist.id

现在,如果您的程序逻辑需要calculate表演者名称:

if performer.band_name is not None:
    performer.name = performer.band_name
else:
    performer.name = performer.first_name + ' ' + performer.last_name

我相信示例代码是自解释的,即使它不是在你的编程语言中,并且考虑到有一些预处理查询的结果来获得示例中使用的performer对象。

答案 3 :(得分:1)

我建议如下。

有一个行为是act_type指示的个别艺术家或乐队(artist_id和band_id都是其各自表的主键和act_id的外键)。乐队是一个或多个艺术家的合作,或者可能是一个以上乐队的合作,或者是一个或多个乐队和一个或多个艺术家的合作。

记录类型指示的是单个歌曲或专辑/ EP的录音(song_id和album_id都是主键或它们各自的表以及recording_id的外键)。专辑/ EP由多首单曲组成。

歌曲必须与行为相关联。但是,专辑可能不会直接与动作相关联,例如编辑专辑。有些行为可能不会自己发布录音,而只会作为乐队的一部分。如果录音本身不可用但仅作为专辑的一部分,则录音可能有也可能没有发行日期。

+---------------------+     +----------+                 +----------------+     +---------------------------+
| ACT_RELATIONSHIPS   |     | ACTS     |                 | RECORDINGS     |     | RECORDING_RELATIONSHIPS   |
+---------------------+     +----------+                 +----------------+     +---------------------------+
| act_relationship_id |-----| act_id   |-----------------| recording_id   |-----| recording_relationship_id |
| parent_act_id       |-----| act_type |                 | recording_type |-----| parent_recording_id       |
| child_act_id        |     +----------+                 | act_id         |     | child_recording_id        |
| start_date          |      |        |                  | release_date   |     +---------------------------+
| end_date            |      |        |                  +----------------+
+---------------------+      |        |                       |      |
                             |        |                       |      |
                  +-------------+  +-----------+    +-----------+  +------------+
                  | ARTISTS     |  | BANDS     |    | SONGS     |  | ALBUMS     |
                  +-------------+  +-----------+    +-----------+  +------------+
                  | artist_id   |  | band_id   |    | song_id   |  | album_id   |
                  | family_name |  | band_name |    | song_name |  | album_name |
                  | given_name  |  +-----------+    +-----------+  +------------+
                  +-------------+

答案 4 :(得分:0)

我同意Barmar的回答,但我会为independent_artist添加一个额外的列,该值将是Yes或No。

艺术家表: * artist_id *名字 *姓 * Independent_Artist