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

Databasestruktur/design

Der er ingen generel regel eller bedste praksis, at fremmednøglerne ikke bør være nullable. Mange gange giver det perfekt mening for en enhed ikke at have et forhold til en anden enhed. For eksempel kan du have en tabel over kunstnere, du sporer, men i øjeblikket har du ingen cd'er optaget af disse kunstnere.

Med hensyn til at have medier (CD, DVD, BluRay), der kan være enten musik/lyd eller software, kan du have en tabel med oplysningerne til fælles og derefter to fremmednøgler, en til hver udvidelsestabel (AudioData og SoftwareData), men en skal være NULL . Dette præsenterer en situation, der blandt andet kaldes en eksklusiv bue. Dette anses generelt for at være...problematisk.

Tænk på en superklasse og to afledte klasser i et OO-sprog som Java eller C++. En måde at repræsentere det i et relationsskema er:

create table Media(
    ID      int not null, -- identity, auto_generated, generated always as identity...
    Type    char( 1 ) not null,
    Format  char( 1 ) not null,
    ... <other common data>,
    constraint PK_Media primary key( ID ),
    constraint FK_Media_Type foreign key( Type )
        references MediaTypes( ID ), -- A-A/V, S-Software, G-Game
    constraint FK_Media_Format foreign key( Format )
        references MediaFormats( ID ) -- C-CD, D-DVD, B-BluRay, etc.
);
create unique index UQ_Media_ID_Type( ID, Type ) on Media;
create table AVData( -- For music and video
    ID       int not null,
    Type     char( 1 ) not null,
    ... <audio-only data>,
    constraint PK_AVData primary key( ID ),
    constraint CK_AVData_Type check( Type = 'A',
    constraint FK_AVData_Media foreign key( ID, Type )
        references Media( ID, Type )
);
create table SWData( -- For software, data
    ID       int not null,
    Type     char( 1 ) not null,
    ... <software-only data>,
    constraint PK_SWData primary key( ID ),
    constraint CK_SWData_Type check( Type = 'S',
    constraint FK_SWData_Media foreign key( ID, Type )
        references Media( ID, Type )
);
create table GameData( -- For games
    ID       int not null,
    Type     char( 1 ) not null,
    ... <game-only data>,
    constraint PK_GameData primary key( ID ),
    constraint CK_GameData_Type check( Type = 'G',
    constraint FK_GameData_Media foreign key( ID, Type )
        references Media( ID, Type )
);

Hvis du nu leder efter en film, søger du i AVData-tabellen, og slutter dig derefter til Media-tabellen for at få resten af ​​informationen og så videre med software eller spil. Hvis du har en ID-værdi, men ikke ved, hvilken slags det er, søg i Medie-tabellen, og Type-værdien vil fortælle dig, hvilken af ​​de tre (eller flere) datatabeller du skal slutte dig til. Pointen er, at FK henviser til den generiske tabel, ikke fra den.

Selvfølgelig kan en film eller et spil eller software frigives på mere end én medietype, så du kan have skæringstabeller mellem Media tabel og de respektive datatabeller. Otoh, disse er generelt mærket med forskellige SKU'er, så du vil måske også behandle dem som forskellige varer.

Koden kan, som du måske forventer, blive ret kompliceret, men ikke så dårlig. Otoh, vores designmål er ikke kodesimpelhed, men dataintegritet. Dette gør det umuligt at blande for eksempel spildata med et filmemne. Og du slipper for at have et sæt felter, hvor kun ét skal have en værdi, og de andre skal være nul.



  1. Simpel MySQL-opdateringsrangering med bånd

  2. ORA-12514 fejl efter genstart af serveren

  3. Sådan vises alle visninger i en PostgreSQL-database

  4. Hent alle overordnede/underordnede poster fra databasen på Laravel (hierarkiske data)