Иногда возникает проблема думать о наличии двух разных ограничений, а не об одном ограничении со специальными условиями.
Например, условие 1: для каждого проекта должен быть назначен старший программист; условие 2: каждый проект может иметь любое количество дополнительных программистов, старших или младших, назначенных ему.
create table Programmers(
ID counter constraint PK_Programmers primary key,
Name text,
Seniority char(1) check(Seniority in('S', 'J'),
...,
constraint UQ_Programmer_seniority unique(ID, Seniority),
constraint CK_Programmer_Seniority check(Seniority in('S', 'J'))
);
create table Project(
ID counter constraint PK_Projects primary key,
Name text,
SrProg int,
SrFlag char(1) default 'S',
...,
constraint SK_Project_SrFlag check(SrFlag = 'S'),
constraint FK_Project_SrProgrammer foreign key(SrProg, SrFlag)
references Programmers(ID, Seniority)
);
Таким образом, старший программист - это 1-1 FK, определенный как часть кортежа проекта. Ссылка не может быть сделана, если программист не определен как «S» (старший), и как только ссылка сделана, «S» для этого программиста не может быть изменен на «J».
Что касается других программистов, используйте стандартную таблицу пересечений. Поскольку старшинство этих программистов не имеет значения, просто используйте PK в ссылке.
create table Project_Programmers(
ProjID int not null,
ProgID int not null,
constraint PK_Project_Programmers primary key(ProjID, ProgID),
constraint FK_Project_Programmers_Project foreign key(ProjID)
references Projects(ID),
constraint FK_Project_Programmers_Programmer foreign key(ProgID)
references Programmers(ID)
);
Поскольку индикатор старшинства не является частью этих FKS, индикатор старшинства «J» может быть изменен на «S» без каких-либо проблем или из «S» к «J», если что программист не определен как обязательный старший программист проекта. Давайте посмотрим правде в глаза, иногда люди должны быть понижены в должности. Это дает вам дополнительную защиту для хранения пониженных программ, назначенных старшим программистом любого проекта. Демонация не может произойти до тех пор, пока они не будут удалены со всех таких позиций.