如何将不同的多个映射到具有相同约束的manys

时间:2011-12-12 20:20:43

标签: sql sql-server database-design constraints data-integrity

我有一个数据模型,我有一些担忧。这是:

enter image description here

我担心的是,可以将应用程序分配给成员,然后将来自不同应用程序的角色分配给该成员。

现在,我知道我可以对此加以限制,以确保不会发生,但这似乎是一个绑带。我宁愿设计模型,以便不需要约束。

是否有人可以建议如何更改模型以确保只能为成员分配角色?

2 个答案:

答案 0 :(得分:2)

通常,当您拆分密钥时会遇到这种问题。修复该分裂键,然后使用重叠的外键约束通常是您正在寻找的。

create table cmember (
  cmemberid integer primary key,
  username varchar(15) not null,
  emailaddress varchar(64) not null
);

create table application (
  applicationid integer primary key,
  description varchar(50) not null
);

create table member_application (
  cmemberid integer not null references cmember (cmemberid),
  applicationid integer not null references application (applicationid),
  primary key (cmemberid, applicationid)
);

create table role (
  roleid integer primary key,
  rolename varchar(25) not null
);

create table crole (
  croleid integer not null references role (roleid),
  -- Include the application id in this table . . .
  applicationid integer not null references application (applicationid),
  -- and make it part of the primary key.
  primary key (croleid, applicationid)
);

create table member_role (
  cmemberid integer not null references cmember (cmemberid),
  croleid integer not null,
  applicationid integer not null,
  primary key (cmemberid, croleid, applicationid),
  -- Note the overlapping foreign key constraints.
  foreign key (croleid, applicationid) references crole (croleid, applicationid),
  foreign key (cmemberid, applicationid) references member_application (cmemberid, applicationid)
);

insert into cmember values (1, 'A', 'A@b.com');
insert into cmember values (2, 'B', 'B@b.com');

insert into application values (1, 'App 1');
insert into application values (2, 'App 2');

insert into member_application values (1, 1);
insert into member_application values (2, 2);

insert into role values (1, 'Admin');

insert into crole values (1, 1);
insert into crole values (1, 2);

insert into member_role values (1, 1, 1);
insert into member_role values (2, 1, 2);

成员1仅分配给应用程序1.因此,尝试插入引用应用程序2的行应该会失败。

insert into member_role values (1,1,2);
ERROR:  insert or update on table "member_role" violates foreign key constraint "member_role_cmemberid_fkey1"
DETAIL:  Key (cmemberid, applicationid)=(1, 2) is not present in table "member_application".

答案 1 :(得分:0)

是,

方法是删除CMemberIDMember_Role的外键,并在此表(Member_Role)中创建一个外键到Member_Application。新外键必须包含两个字段:ApplicationID + CRoleID

现在:

Member_Role ( CMemberID , CROleID )
PK = CMemberID + CROleID
FK1 (to CMember) =  CMemberID
FK2 (to CRole) = CRoleId

解决方案:

CRole: Create unique constraint on CRoleID + ApplicationID
Member_Application: create unique constraint on CMemberID + ApplicationID
Member_Role ( CMemberID , ApplicationID, CRoleID )
PK = CMemberID + ApplicationID + CRoleID
FK1 (to Member_Application) = CMemberID + ApplicationID
FK2 (to CRole) = ApplicationID + CRoleID