Вот несколько возможностей. Одним из них является CHECK
в каждой таблице, которое student_id
не отображается ни в одной из других дочерних таблиц подтипов. Это, вероятно, дорого, и каждый раз, когда вам нужен новый подтип, вам нужно изменить ограничение во всех существующих таблицах.
CREATE TABLE athletes (
student_id INT NOT NULL PRIMARY KEY,
FOREIGN KEY (student_id) REFERENCES students(student_id),
CHECK (student_id NOT IN (SELECT student_id FROM musicians
UNION SELECT student_id FROM slackers
UNION ...))
);
edit: @JackPDouglas правильно указывает, что вышеуказанная форма ограничения CHECK не поддерживается Microsoft SQL Server. Фактически, в соответствии со стандартом SQL-99 недопустимо ссылаться на другую таблицу (см. http://kb.askmonty.org/v/constraint_type-check-constraint).
SQL-99 определяет объект метаданных для ограничений нескольких таблиц. Это называется ASSERTION , однако я не знаю ни одной СУБД, реализующей утверждения.
Вероятно, лучше сделать первичный ключ в таблице students
составным первичным ключом, второй столбец обозначает подтип. Затем ограничьте этот столбец в каждой дочерней таблице одним значением, соответствующим подтипу, представленному таблицей. edit: нет необходимости делать PK составным ключом в дочерних таблицах.
CREATE TABLE athletes (
student_id INT NOT NULL PRIMARY KEY,
student_type CHAR(4) NOT NULL CHECK (student_type = 'ATHL'),
FOREIGN KEY (student_id, student_type) REFERENCES students(student_id, student_type)
);
Конечно, student_type
может быть просто целым числом, я просто показываю его как символ для иллюстрации.
Если у вас нет поддержки CHECK
ограничений (например, MySQL), то вы можете сделать нечто подобное в триггере.
Я прочитал ваше продолжение о том, чтобы убедиться, что в некоторой таблице подклассов есть строка для каждой строки в таблице суперкласса. Я не думаю, что есть практический способ сделать это с метаданными SQL и ограничениями. Единственный вариант, который я могу предложить для удовлетворения этого требования, - это использовать Single-Table Inheritance . В противном случае вам нужно полагаться на код приложения для обеспечения его соблюдения.
edit: JackPDouglas также предлагает использовать дизайн, основанный на наследовании таблиц классов . См. его пример или мои примеры подобной техники здесь или здесь или здесь .