Проблема ограничения целостности в реляционной модели наследования с MySQL 5.5 - PullRequest
0 голосов
/ 14 сентября 2011

У меня есть следующая реляционная схема базы данных, предназначенная для моделирования супертипа EMP вместе с двумя подтипами FULL_TIME_EMP и PART_TIME_EMP:

database schema У меня проблема с честностью, то есть я хотел бы убедиться, что у штатного сотрудника может быть только соответствующая строка в таблице FULL_TIME_EMP, и аналогичным образом у работника с частичной занятостью может быть только соответствующая строка в таблице PART_TIME_EMP. 1004 *

Как вы увидите из снимков экрана ниже, это ограничение целостности не применяется.

Вот таблица EMP_TYPE: EMP_TYPE table

И таблица ПУОС: EMP table

Таблица PART_TIME_EMP: PART_TIME_EMP table

И, наконец, таблица FULL_TIME_EMP, которая представляет нарушение целостности !! FULL_TIME_EMP table

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

С уважением,

1 Ответ

3 голосов
/ 14 сентября 2011

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

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

Вот как я бы написал это для более стандартной платформы SQL.

create table emp (
  emp_id integer primary key,
  emp_type char(1) not null check (emp_type in ('f', 'p')), -- FK in your schema
  emp_name varchar(50) not null,
  start_date date not null default current_date,
  unique (emp_id, emp_type)
);

create table full_time_emp (
  emp_id integer primary key references emp (emp_id),
  emp_type char(1) not null default 'f' check (emp_type = 'f'),
  foreign key (emp_id, emp_type) references emp (emp_id, emp_type),
  salary decimal(14,2) not null check (salary > 15000)
);

create table part_time_emp (
  emp_id integer primary key references emp (emp_id),
  emp_type char(1) not null default 'p' check (emp_type = 'p'),
  foreign key (emp_id, emp_type) references emp (emp_id, emp_type),
  rate decimal(14,2) not null check (rate > 0 and rate < 100)
);

В таблице full_time_emp эти два ограничения

  check (emp_type = 'f'),
  foreign key (emp_id, emp_type) references emp (emp_id, emp_type),

в совокупности не позволяет сотрудникам, занятым неполный рабочий день, появляться в таблице полной занятости. Если указанная строка в «emp» содержит «p», ссылка на внешний ключ не будет выполнена; если вы попытаетесь вставить «p» в «full_time_emp», проверка не будет выполнена.

В этом случае вы можете заменить проверочное ограничение однострочной таблицей и ссылкой на внешний ключ. Таблица должна содержать только «F». (Или любой другой идентификационный номер, который вы используете для представления сотрудника, работающего полный рабочий день.) То же самое работает для "part_time_emp". Таким образом, вместо ограничения CHECK, вы можете сделать this для full_time_emp.

create table full_time_emp_check (
  full_time_emp_type char(1) primary key
);
insert into full_time_emp_check values ('f');

alter table full_time_emp
add constraint full_time_emp_check
foreign key (emp_type) references full_time_emp_check (full_time_emp_type);

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

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

ИМХО, код CHAR (1) лучше, чем целое число для типов сотрудников. Читаемый человеком код не требует объединения.

...