Если пользователь не может быть одновременно учителем и учеником, то вы смотрите на простую проблему супертипа / подтипа.(Я использую супертип и подтип в смысле проектирования реляционных баз данных, а не в смысле объектно-ориентированного программирования.) Вы вправе хранить в «учениках» только эти атрибутыкоторые описывают учеников и хранят в «учителях» только те атрибуты, которые описывают учителей.
-- Supertype: users
create table users (
user_id integer not null unique,
user_type char(1) not null
check (user_type in ('T', 'S')),
-- other user columns
primary key (user_id, user_type)
);
-- Subtype: students
create table students_st (
user_id integer not null,
user_type char(1) not null default 'S'
check (user_type = 'S'),
locker_num integer not null unique
check (locker_num > 0),
-- other student columns
primary key (user_id, user_type),
foreign key (user_id, user_type)
references users (user_id, user_type)
on delete cascade
);
-- Subtype: teachers
create table teachers_st (
user_id integer not null,
user_type char(1) not null default 'T'
check (user_type = 'T'),
office_num char(4),
-- other teacher columns
primary key (user_id, user_type),
foreign key (user_id, user_type)
references users (user_id, user_type)
on delete cascade
);
create view teachers as
select u.user_id,
u.user_type,
-- other user columns
t.office_num
-- other teacher columns
from users u
inner join teachers_st t on (u.user_id = t.user_id);
create view students as
select u.user_id,
u.user_type,
-- other user columns
s.locker_num
-- other student columns
from users u
inner join students_st s on (u.user_id = s.user_id);
На этом этапе вы также будете делать все, что требуется вашей базе данных, чтобы сделать эти два представления обновляемыми:, без разницы.Код приложения вставляет, обновляет и удаляет из представлений, а не из базовых таблиц.