sql >> Databasteknik >  >> RDS >> Mysql

Designa relationer kring en arvsstruktur

Det finns en liknande fråga här använda en mediasupertyp och lägga till undertyper av CD, VCR, DVD, etc.

Detta är skalbart genom att när du skapar, säg, en BluRay-undertyp, skapar du tabellen för att innehålla BluRay-specifika data och lägger till en post i MediaTypes-tabellen. Inga ändringar behövs för befintlig data eller kod -- förutom, naturligtvis, att lägga till koden som fungerar med BluRay-data.

I ditt fall skulle användare vara supertyptabellen med lärare och elever undertyptabellerna.

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 )
);

Uppsättningen av elevbordet skulle likna Lärarbordet.

Eftersom både lärare och elever kan anställa andra lärare och elever, skulle tabellen som innehåller denna relation hänvisa till tabellen Användare.

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 )
);

Som jag förstår det grupperas meddelanden efter arbetsgivare:

create table Notifications(
    EmployerID    int not null
    NotificationDate date,
    NotificationData varchar( 500 ),
    -- other notification data...,
    constraint FK_NotificationsEmployer foreign key( EmployerID )
        references Users( ID )
);

Frågorna bör vara enkla nog. Till exempel, om en användare vill se alla meddelanden från sin(a) arbetsgivare:

select  e.EmployerID, n.NotificationDate, n.NotificationData
from    Employment  e
join    Notifications n
    on  n.EmployerID = e.EmployerID
where   e.EmployeeID = :UserID;

Detta är förstås en första skiss. Förfinningar är möjliga. Men till dina numrerade punkter:

  1. Tabellen Sysselsättning relaterar arbetsgivare till anställda. Den enda kontrollen om att göra användaren arbetsgivare kan inte anställa sig själva, men annars kan alla användare vara både anställd och arbetsgivare.
  2. Tabellen Användare tvingar varje användare att vara antingen lärare ('T') eller elev ('S'). Endast användare definierade som 'T' kan placeras i tabellen Lärare och endast användare som definieras som 'S' kan placeras i tabellen Elever.
  3. Anställningstabellen ansluter endast till tabellen Användare, inte till både Lärare och Elever. Men det beror på att både lärare och elever kan vara både arbetsgivare och anställda, inte av någon prestationsskäl. I allmänhet, oroa dig inte för prestanda under den första designen. Ditt primära bekymmer vid denna tidpunkt är dataintegritet. Relationsdatabaser är mycket bra med joins. Om ett prestandaproblem bör dyka upp och åtgärda det sedan. Omstrukturera inte dina data för att lösa problem som ännu inte finns och kanske aldrig finns.
  4. Tja, prova det här och se hur det fungerar.



  1. SQL-fråga för att få aggregerade resultat i kommaavgränsare tillsammans med grupp för kolumn i SQL Server

  2. Passerar array genom AJAX från php till javascript

  3. Kör en lagrad procedur i en annan lagrad procedur i SQL-servern

  4. MySQL VARCHAR Lengths och UTF-8