CREATE TABLE People
(
PersonID INTEGER NOT NULL PRIMARY KEY, -- Add local incantation for auto-allocated numbers
FirstName VARCHAR(32) NOT NULL,
LastName VARCHAR(32) NOT NULL,
Email VARCHAR(64) NOT NULL UNIQUE,
UserName VARCHAR(16) NOT NULL UNIQUE,
PersonType CHAR(1) NOT NULL CHECK(PersonType IN('S', 'T')) -- S student, T teacher
);
CREATE TABLE Student
(
PersonID INTEGER NOT NULL REFERENCES People,
A ...,
B ...,
C ...,
D ...
);
CREATE TABLE Teacher
(
PersonID INTEGER NOT NULL REFERENCES People,
E ...,
F ...,
G ...
);
Существует ограничение, которое требуется принудительно, чтобы столбец Teacher.PersonID ссылался на строку в People, где PersonType = 'T'
, и аналогично для Student.PersonID, ссылающейся на строку в People, где PersonType = 'S'
. * 1004.*
Нет особо чистого способа обеспечить это автоматически.Вы можете добавить столбец PersonType для каждого учителя и ученика, который всегда будет содержать «T» или «S», а затем создать внешний ключ, который ссылается на People (PersonID, PersonType).Это некрасиво, потому что значение в таблице «Учитель» или «Студент» является постоянным, и поскольку один только PersonID уникален.
В противном случае вы применяете ограничения в коде.Вероятно, я бы использовал код, подкрепленный периодической проверкой, для записей, которые нарушают ограничение (записи в Teacher, которые идентифицируют ученика в таблице People, или записи в Student, которые идентифицируют учение в таблице People).
Насколько хорошо это отображается в Hibernate - это отдельная проблема.Возможно, вам пригодятся два представления:
CREATE VIEW StudentInfo AS
SELECT P.*, S.A, S.B, SS.C, S.D
FROM People AS P
JOIN Student AS S
ON P.PersonID = S.PersonID AND P.PersonType = 'S';
CREATE VIEW TeacherInfo AS
SELECT P.*, T.E T.F, T.G
FROM People AS P
JOIN Teacher AS T
ON P.PersonID = T.PersonID AND P.PersonType = 'T';
Конечно, вы можете убедительно утверждать, что ограничения на PersonType не нужны.