由两个主键标识的值的数据库设计

Database Design of a value identified by two Primary Keys

我有 table 的 event_id、role_id 和排名。 以下 table 应该有助于可视化我们期望的关于我们的约束的各种结果:

   scenario    Event_Id    Role_Id    Rank
      1            1           1        1    good
      2            1           2        1    bad
      3            2           1        1    good

Event_Id 是事件 table 的主键。
Role_Id 是角色 table 的主键。
使用事件和角色,我们找到与给定事件的角色关联的等级。

一个角色可以在不同段位的多个事件中使用(场景1和3)
但是,对于同一事件,2 个角色不应具有相同的等级。 (场景 1 和 2)

我们如何建立这些约束,以便我们可以确定给定事件中给定角色的等级,但角色的等级仅在该事件中是唯一的?

您需要有两个唯一约束。

第一个是你的 "natural" Event_Id 加上 Role_Id 的候选键。这意味着对于任何给定的事件和角色组合,您只有一个可能的 Rank 值。

现在,要强制执行任何给定事件只能有一个具有给定等级的角色的约束,您需要 第二个唯一约束 Event_Id 的组合加上 Rank.

为什么 Rank 对于不同的 具有相同的 候选主键

Rank = 1 表示 ...

如果 Rank 是由如下集合描述的实体:

  • 1 -> 差
  • 2 -> 好

那么你可以设计:

create table Events(EventId int, primary key(EventId))
create table Roles(RoleId int, primary key(RoleId))
create table Ranks(RankId int, Title varchar(...), primary key(RankId))    
create table EventRoleRank(
    EventId int,
    RoleId int,
    RankId int,
    primary key(EventId, RoleId, RankId)
)

在此设计中,RankId 必须表示 BadGood不能同时表示

如果,否则,RankId = 1 必须在一种情况下表示 Bad 而在另一种情况下表示 Good,则:

create table Events(EventId int, primary key(EventId))
create table Roles(RoleId, primary key(RoleId))
create table EventRoleRank(
    EventId int,
    RoleId int,
    RankId int,
    RankTitle varchar(...),
    primary key(EventId, RoleId)
)

insert into EventRoleRank(1, 1, 1, 'good')
insert into EventRoleRank(1, 2, 1, 'bad')