我有一个数据模型,我对此有些担心。这里是:
我担心的是可以将应用程序分配给成员,然后将来自不同应用程序的角色分配给成员。
现在,我知道我可以对此进行限制以确保不会发生这种情况,但这似乎是一个创可贴。我宁愿设计模型,以便不需要约束。
谁能建议如何更改模型以确保只能从分配给它的应用程序中为成员分配角色?
我有一个数据模型,我对此有些担心。这里是:
我担心的是可以将应用程序分配给成员,然后将来自不同应用程序的角色分配给成员。
现在,我知道我可以对此进行限制以确保不会发生这种情况,但这似乎是一个创可贴。我宁愿设计模型,以便不需要约束。
谁能建议如何更改模型以确保只能从分配给它的应用程序中为成员分配角色?
通常,您在拆分密钥时会遇到此类问题。修复该拆分键,然后使用重叠的外键约束通常是您正在寻找的。
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".
是的,
方法是删除外键到CMemberID
inMember_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