Neexistuje žádné obecné pravidlo ani doporučený postup, že by cizí klíče neměly mít hodnotu null. Mnohokrát dává dokonalý smysl, aby entita neměla vztah s jinou entitou. Můžete mít například tabulku interpretů, které sledujete, ale v tuto chvíli nemáte žádná CD nahraná těmito umělci.
Pokud jde o média (CD, DVD, BluRay), která mohou být hudební/audio nebo software, můžete mít tabulku se společnými informacemi a pak dva cizí klíče, jeden pro každou tabulku rozšíření (AudioData a SoftwareData), ale jeden musí být NULL
. To představuje situaci nazývanou mimo jiné exkluzivní oblouk. Toto je obecně považován za...problematický.
Představte si supertřídu a dvě odvozené třídy v OO jazyce, jako je Java nebo C++. Jedním ze způsobů, jak to reprezentovat v relačním schématu, je:
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 )
);
Nyní, pokud hledáte film, prohledejte tabulku AVData, poté se spojte s tabulkou Media pro zbytek informací a tak dále se softwarem nebo hrami. Pokud máte hodnotu ID, ale nevíte, jaký je to druh, prohledejte tabulku Media a hodnota Type vám řekne, ke které ze tří (nebo více) datových tabulek se připojit. Jde o to, že FK odkazuje na na z obecné tabulky, nikoli z ní.
Film, hra nebo software lze samozřejmě vydat na více než jednom typu média, takže mezi Media
můžete mít průsečíkové tabulky. tabulky a příslušných datových tabulek. Otoh, ty jsou obecně označeny různými SKU, takže s nimi možná budete chtít zacházet jako s různými položkami.
Kód, jak byste mohli očekávat, může být poměrně komplikovaný, i když ne tak špatný. Otoh, naším cílem není jednoduchost kódu, ale integrita dat. To znemožňuje smíchat například herní data s položkou filmu. A zbavíte se sady polí, kde pouze jedno musí mít hodnotu a ostatní musí být null.