Chiave surrogata come chiave esterna rispetto a chiavi composite
-
06-07-2019 - |
Domanda
Mi rendo conto che potrebbero esserci domande simili, ma non sono riuscito a trovarne una che fosse abbastanza vicina come guida.
Date queste specifiche,
Site
---------------------------
SiteID int identity
Name varchar(50)
Series
---------------------
SiteID int
SeriesCode varchar(6)
...
--SeriesCode will be unique for every unique SiteID
Episode
----------------------
SiteID int
SeriesCode varchar(6)
EpisodeCode varchar(10)
...
il mio progetto / implementazione proposti è
Site
----------------------------
SiteID int identity
Name varchar(50)
Series
-------------------------------------------
SeriesID int identity, surrogate key
SiteID int natural key
SeriesCode varchar(6) natural key
UNIQUE(SiteID, SeriesCode)
...
Episode
-------------------------------------------
EpisodeID int identity, surrogate key
SeriesID int foreign key
EpisodeCode varchar(6) natural key
...
Qualcosa non va in questo? Va bene avere il surrogato SeriesID come chiave esterna * qui? Non sono sicuro che mi manchino eventuali problemi evidenti che possono sorgere. O sarebbe meglio usare chiavi naturali composite (SiteID + SeriesCode / SiteID + EpisodeCode)? In sostanza, ciò separerebbe il tavolo degli episodi dal tavolo della serie e non mi farebbe comodo.
Vale la pena aggiungere che SeriesCode assomiglia a "ABCD-1" e EpisodeCode come "ABCD-1NMO9" nei dati di input non elaborati che popoleranno queste tabelle, quindi suppongo che sia un'altra cosa che potrebbe essere cambiata.
*: "virtuale" chiave esterna, poiché è stato precedentemente deciso dai piani superiori che non dovremmo usare chiavi effettive
Soluzione
Sì, sembra tutto a posto. L'unico punto (minore) che potrei mettere in evidenza è che, a meno che tu non abbia un altro quarto tavolo figlio sospeso fuori da Episode, probabilmente non hai bisogno di EpisodeId, in quanto Episode.EpisodeCode è una chiave naturale a singolo attributo sufficiente per identificare e localizzare le righe nell'episodio. Naturalmente non è dannoso lasciarlo lì, ma come regola generale aggiungo chiavi surrogate per fungere da target per gli FK nelle tabelle figlio e provo ad aggiungere una chiave narurale a ogni tabella per identificare e controllare le righe di dati ridondanti ... Quindi se una tabella non ha un'altra tabella con un FK che fa riferimento a essa, (e mai lo farò) a volte non mi preoccupo di includere una chiave surrogata in essa.
Altri suggerimenti
Che cos'è un " virtuale " chiave esterna? I superiori hanno deciso di non utilizzare vincoli di chiave esterna? In tal caso, non si utilizzano affatto chiavi esterne. Stai solo fingendo di farlo.
E Episodio è la scelta migliore per un'entità? Non significa davvero Show o Podcast o giù di lì, e capita sempre di far parte di una serie in questo momento? In tal caso, questo cambierà in futuro? Alla fine Episodio verrà abusato di includere lo Show al di fuori di una serie? In tal caso, legare Episodio al sito tramite la serie potrebbe tornare a perseguitarti.
Considerato tutto ciò, e supponendo che tu come un grugnito probabilmente non puoi cambiarlo: se fossi in te mi sentirei più sicuro usando le chiavi naturali ovunque possibile. In assenza di vincoli di chiave esterna, facilita il riconoscimento dei dati errati e se in seguito si dovrà ricorrere ad alcuni stratagemmi SeriesCode = 'EMPTY' è più facile anche con le chiavi naturali.
Il mio suggerimento:
Utilizza naturale / commerciale come chiave primaria quando possibile tranne nelle seguenti 3 situazioni:
- La chiave naturale / commerciale è sconosciuta al momento dell'inserimento
- La chiave naturale / commerciale non è non valida (non è univoca, è soggetta a modifiche frequenti)
- La chiave naturale / commerciale è un composto di più di 3 colonne e la tabella avrà tabelle secondarie
Nelle situazioni 1 e 2 una chiave surrogata è richiesta .
Nella situazione 3 una chiave surrogata è fortemente consigliata .