Er is een vergelijkbare vraag hier een media-supertype gebruiken en subtypen cd, videorecorder, dvd, enz. toevoegen.
Dit is schaalbaar doordat u bij het maken van bijvoorbeeld een BluRay-subtype de tabel maakt om de BluRay-specifieke gegevens te bevatten en een item toevoegt aan de MediaTypes-tabel. Er zijn geen wijzigingen nodig voor bestaande gegevens of code -- behalve natuurlijk om de code toe te voegen die werkt met BluRay-gegevens.
In jouw geval zouden Gebruikers de supertypetabel zijn met Docenten en Studenten de subtypetabellen.
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 )
);
De samenstelling van de tabel Studenten zou vergelijkbaar zijn met de tabel Docenten.
Aangezien zowel docenten als studenten andere docenten en studenten in dienst kunnen nemen, verwijst de tabel met deze relatie naar de tabel Gebruikers.
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 )
);
Zoals ik het begrijp, zijn meldingen gegroepeerd per werkgever:
create table Notifications(
EmployerID int not null
NotificationDate date,
NotificationData varchar( 500 ),
-- other notification data...,
constraint FK_NotificationsEmployer foreign key( EmployerID )
references Users( ID )
);
De vragen moeten eenvoudig genoeg zijn. Als een gebruiker bijvoorbeeld alle meldingen van zijn werkgever(s) wil zien:
select e.EmployerID, n.NotificationDate, n.NotificationData
from Employment e
join Notifications n
on n.EmployerID = e.EmployerID
where e.EmployeeID = :UserID;
Dit is natuurlijk een eerste schets. Verfijningen zijn mogelijk. Maar op uw genummerde punten:
- De tabel Werkgelegenheid relateert werkgevers aan werknemers. De enige manier om te controleren of gebruikers werkgevers niet zelf in dienst kunnen nemen, maar verder kan elke gebruiker zowel werknemer als werkgever zijn.
- De tabel Gebruikers dwingt elke gebruiker om ofwel een leraar ('T') of student ('S') te zijn. Alleen gebruikers die zijn gedefinieerd als 'T' kunnen in de tabel Docenten worden geplaatst en alleen gebruikers die zijn gedefinieerd als 'S' kunnen in de tabel Studenten worden geplaatst.
- De tabel Werkgelegenheid wordt alleen samengevoegd met de tabel Gebruikers, niet met zowel de tabellen Docenten als Studenten. Maar dit komt omdat zowel docenten als studenten zowel werkgevers als werknemers kunnen zijn, niet om prestatieredenen. Over het algemeen hoeft u zich tijdens het eerste ontwerp geen zorgen te maken over de prestaties. Uw voornaamste zorg op dit punt is de gegevensintegriteit. Relationele databases zijn erg goed met joins. Als er zou een prestatieprobleem moeten optreden en dit vervolgens oplossen. Herstructureer uw gegevens niet om problemen op te lossen die nog niet bestaan en misschien nooit zullen bestaan.
- Nou, probeer dit eens en kijk hoe het werkt.