Podobná otázka je zde pomocí nadtypu média a přidáním podtypů CD, VCR, DVD atd.
To je škálovatelné v tom, že při vytváření, řekněme, podtypu BluRay, vytvoříte tabulku, která bude obsahovat data specifická pro BluRay, a přidáte položku do tabulky MediaTypes. Pro existující data nebo kód nejsou potřeba žádné změny – samozřejmě kromě přidání kódu, který bude pracovat s BluRay daty.
Ve vašem případě by uživatelé byli tabulkou nadtypu a tabulkami podtypů Učitelé a Studenti.
create table Users(
ID int not null auto_generating,
Type char( 1 ) check( Type in( 'T', 'S' )),
-- other data common to all users,
constraint PK_Users primary key( ID ),
constraint UQ_UserType unique( ID, Type ),
constraint FK_UserTypes foreign key( Type )
references UserTypes( ID )
);
create table Teachers(
TeacherID int not null,
TeacherType char( 1 ) check( TeacherType = 'T' )),
-- other data common to all teachers...,
constraint PK_Teachers primary key( TeacherID ),
constraint FK_TeacherUser foreign key( TeacherID, TeacherType )
references Users( ID, Types )
);
Složení tabulky Studenti by bylo podobné jako u tabulky Učitelé.
Protože učitelé i studenti mohou zaměstnávat další učitele a studenty, bude tabulka obsahující tento vztah odkazovat na tabulku Uživatelé.
create table Employment(
EmployerID int not null,
EmployeeID int not null,
-- other data concerning the employment...,
constraint CK_EmploymentDupes check( EmployerID <> EmployeeID ),
constraint PK_Employment primary key( EmployerID, EmployeeID ),
constraint FK_EmploymentEmployer foreign key( EmployerID )
references Users( ID ),
constraint FK_EmploymentEmployee foreign key( EmployeeID )
references Users( ID )
);
Pokud tomu dobře rozumím, oznámení jsou seskupena podle zaměstnavatele:
create table Notifications(
EmployerID int not null
NotificationDate date,
NotificationData varchar( 500 ),
-- other notification data...,
constraint FK_NotificationsEmployer foreign key( EmployerID )
references Users( ID )
);
Dotazy by měly být dostatečně jednoduché. Pokud například uživatel chtěl vidět všechna oznámení od svého zaměstnavatele:
select e.EmployerID, n.NotificationDate, n.NotificationData
from Employment e
join Notifications n
on n.EmployerID = e.EmployerID
where e.EmployeeID = :UserID;
Toto je samozřejmě prvotní skica. Upřesnění jsou možná. Ale k vašim očíslovaným bodům:
- Tabulka Zaměstnanost uvádí vztah mezi zaměstnavateli a zaměstnanci. Jedinou kontrolou, pokud chcete, aby uživatelé byli zaměstnavatelé, nemohou být zaměstnanci sami, ale jinak může být každý uživatel současně zaměstnancem i zaměstnavatelem.
- Tabulka Uživatelé nutí každého uživatele, aby byl buď učitelem ('T') nebo studentem ('S'). Do tabulky Učitelé lze umístit pouze uživatele definované jako „T“ a do tabulky Studenti lze umístit pouze uživatele definované jako „S“.
- Tabulka Zaměstnání se připojuje pouze k tabulce Uživatelé, nikoli k tabulkám Učitelé a Studenti. Ale to proto, že jak učitelé, tak studenti mohou být zaměstnavateli i zaměstnanci, a to ne z jakéhokoli výkonnostního důvodu. Obecně se při počátečním návrhu nebojte o výkon. Vaším hlavním zájmem je v tomto bodě integrita dat. Relační databáze jsou velmi dobré se spojeními. Pokud měl by se objevit problém s výkonem a poté jej opravit. Nerestrukturalizujte svá data, abyste vyřešili problémy, které dosud neexistují a možná nikdy existovat nebudou.
- No, zkuste to a uvidíte, jak to funguje.