sql >> Databáze >  >> RDS >> Mysql

Navrhování vztahů kolem struktury dědictví

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:

  1. 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.
  2. 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“.
  3. 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.
  4. No, zkuste to a uvidíte, jak to funguje.



  1. MySQL INSERT DO WHERE NOT EXIST

  2. Funkce Javascript post a volání php skriptu

  3. Jak Access komunikuje se zdroji dat ODBC? Část 3

  4. Odstraňte prázdné místo na konci v obsahu pole