sql >> Database >  >> RDS >> Mysql

DB-ontwerpvraag over nullable buitenlandse sleutels en normalisatie

Sommige zeer goede ontwerpers gebruiken NULL's in externe sleutels zonder nadelige gevolgen. Ik leun zelf ook zo. Een nullable FK vertegenwoordigt een optionele relatie. In gevallen waarin de entiteit geen relatie heeft, bevat de FK een NULL. De ruimte boven je hoofd is minimaal. Wanneer joins (equijoins, om precies te zijn) worden gedaan over de twee tabellen, zullen instanties die NULL in de FK bevatten, uit de join vallen, en dat is gepast.

Dat gezegd hebbende, ga ik je een vierde methode aanbevelen. Dit omvat in totaal 4 tabellen, accounts, widgets, typen en custom_types. De tabel custom_types gebruikt een techniek genaamd Shared-primary-key, die hieronder wordt beschreven.

CREATE TABLE accounts (
    account_id  INT UNSIGNED AUTO_INCREMENT NOT NULL, 
    # Other Columns...,
    PRIMARY KEY (account_id)
    );  
CREATE TABLE widgets (
    widget_id   INT UNSIGNED AUTO_INCREMENT NOT NULL,
    account_id  INT UNSIGNED NOT NULL, 
    type_id     INT UNSIGNED NOT NULL,
    PRIMARY KEY (widget_id),
    FOREIGN KEY (account_id) REFERENCES accounts(account_id) ON DELETE CASCADE,
    FOREIGN KEY (type_id) REFERENCES types(type_id)
    );  
CREATE TABLE types (
    type_id     INT UNSIGNED AUTO_INCREMENT NOT NULL,
    account_id  INT UNSIGNED NOT NULL, 
    name        VARCHAR(100) NOT NULL,
    PRIMARY KEY (type_id),
    FOREIGN KEY (account_id) REFERENCES accounts(account_id)
CREATE TABLE custom_types (
    type_id     INT NOT NULL,
    account_id  INT UNSIGNED NOT NULL, 
    PRIMARY KEY (type_id),
    FOREIGN KEY (type_id) REFERENCES types(type_id),
    FOREIGN KEY (account_id) REFERENCES accounts(account_id)

);

De kolom type_id in custom_types is een gedeelde primaire sleutel. Merk op dat het zowel als primaire sleutel als als refererende sleutel wordt gedeclareerd, en dat het geen autonummering gebruikt. Het is een kopie van de primaire sleutel in typen voor het bijbehorende item. De tabel met aangepaste typen bevat alle gegevens die aanwezig zijn in aangepaste typen, maar afwezig zijn in vooraf ingestelde typen.

Voor vooraf ingestelde typen wordt een invoer gemaakt in typen, maar wordt er geen invoer gemaakt in custom_types. Voor custom_types wordt eerst een invoer gemaakt in typen, en vervolgens wordt de resulterende waarde van type_id gekopieerd naar custom_types, samen met de account_id.

Als u INNER JOIN-typen en custom_types gebruikt, vallen de vooraf ingestelde typen uit de join. Als u zowel aangepaste als vooraf ingestelde typen in een enkele join wilt, moet u een LEFT JOIN of een RIGHT JOIN gebruiken om dat effect te krijgen. Merk op dat het resultaat van een LEFT of RIGHT JOIN enkele NULL's zal bevatten, ook al worden die NULL's niet opgeslagen in de database.

Klikken op deze geeft u een meer gedetailleerde beschrijving van de gedeelde primaire sleuteltechniek.



  1. Gegevens kopiëren naar een andere tabel

  2. Equivalent van GroupBy en Having-clausule in relationele algebra

  3. ODBC gebruiken met Salesforce en Active Directory Federation Services (ADFS) Single Sign On (SSO)

  4. Voorwaardelijke JOIN-instructie SQL Server