Mysql
 sql >> Database >  >> RDS >> Mysql

Progettare relazioni attorno a una struttura ereditaria

C'è una domanda simile qui utilizzando un supertipo di supporto e aggiungendo sottotipi di CD, VCR, DVD, ecc.

Questo è scalabile in quanto nella creazione, ad esempio, di un sottotipo BluRay, crei la tabella per contenere i dati specifici di BluRay e aggiungi una voce alla tabella MediaTypes. Non sono necessarie modifiche per i dati o il codice esistenti, tranne, ovviamente, per aggiungere il codice che funzionerà con i dati BluRay.

Nel tuo caso, Utenti sarebbe la tabella dei supertipi con Insegnanti e Studenti le tabelle dei sottotipi.

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

La composizione del tavolo Studenti sarebbe simile a quella degli insegnanti.

Poiché sia ​​gli insegnanti che gli studenti possono assumere altri insegnanti e studenti, la tabella che contiene questa relazione farebbe riferimento alla tabella Utenti.

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

A quanto ho capito, le notifiche sono raggruppate per datore di lavoro:

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

Le domande dovrebbero essere abbastanza semplici. Ad esempio, se un utente desidera visualizzare tutte le notifiche dei suoi datori di lavoro:

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

Questo è uno schizzo iniziale, ovviamente. Sono possibili perfezionamenti. Ma ai tuoi punti numerati:

  1. La tabella Occupazione mette in relazione i datori di lavoro con i dipendenti. L'unico controllo se per rendere utenti i datori di lavoro non possono essere dipendenti, ma in caso contrario qualsiasi utente può essere sia un dipendente che un datore di lavoro.
  2. La tabella Utenti obbliga ogni utente a essere un insegnante ('T') o uno studente ('S'). Solo gli utenti definiti come 'T' possono essere inseriti nella tabella Insegnanti e solo gli utenti definiti come 'S' possono essere inseriti nella tabella Studenti.
  3. La tabella Occupazione si unisce solo alla tabella Utenti, non a quella Docenti e Studenti. Ma questo perché sia ​​gli insegnanti che gli studenti possono essere sia datori di lavoro che dipendenti, non per nessun motivo di rendimento. In generale, non preoccuparti delle prestazioni durante la progettazione iniziale. La tua preoccupazione principale a questo punto è l'integrità dei dati. I database relazionali sono molto buoni con i join. Se dovrebbe sorgere un problema di prestazioni, quindi risolverlo. Non ristrutturare i tuoi dati per risolvere problemi che ancora non esistono e che potrebbero non esistere mai.
  4. Bene, provalo e vedi come funziona.