Как отобразить разное множество в manys с одинаковым ограничением - PullRequest
3 голосов
/ 13 декабря 2011

У меня есть модель данных, которая вызывает у меня некоторые опасения. Вот оно:

enter image description here

Меня беспокоит, что можно назначить приложение участнику, а затем назначить ему роль из другого приложения.

Теперь я знаю, что могу наложить на это ограничение, чтобы этого не произошло, но это похоже на бандитизм. Я предпочел бы спроектировать модель так, чтобы ограничение не требовалось.

Кто-нибудь может подсказать, как изменить модель, чтобы члену могли назначаться роли только из приложения, которому он назначен?

Ответы [ 2 ]

2 голосов
/ 13 декабря 2011

Обычно вы сталкиваетесь с такой проблемой, когда вы разделяете ключ.Исправление этого разделенного ключа, а затем использование перекрывающихся ограничений внешнего ключа - это обычно то, что вы ищете.

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".
0 голосов
/ 13 декабря 2011

Да,

способ состоит в том, чтобы удалить внешний ключ для CMemberID в Member_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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...