2015-04-19 2 views
0

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

  • Один стол для Projects
  • Другая таблица для Programmers
  • программист может быть Senior или Junior
  • Каждый проект может иметь несколько программистов, но не менее один старший должен существовать.

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

Я не знаю, как создать такой тип ограничений, не прибегая к какой-либо бизнес-логике.

ответ

0

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

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

Что вы хотите, это в основном триггер, который проверяет определенные ограничения, но Access не поддерживает триггеры базы данных. Обходной путь заключается в том, чтобы атрибут старшего младшего возраста изменялся только в форме. В этой форме вы подключаете событие AfterUpdate-событие или BeforeUpdate-событие к текстовому полю, привязанному к атрибуту, и проверяете бизнес-логику с помощью VBA-кода.

То же самое относится к вашему ограничению по крайней мере с одним старшим.

Может ли какой-нибудь код помочь еще дальше?

0

Иногда возникает проблема думать о наличии двух разных ограничений, а не об одном ограничении со специальными условиями.

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

Смежные вопросы