A quanto ho capito, la terza forma normale (3NF) significa sostanzialmente che dovrebbe esserci esattamente una chiave.
No. 2NF, 3NF e Boyce Codd Normal Form (BCNF) si occupano di dipendenze funzionali . Una tabella in 2NF indica che non vi sono dipendenze di chiavi parziali in cui una colonna non chiave dipende da un sottoinsieme corretto di una chiave multi-colonna. Tabelle come quella del nostro esempio sono già in 2NF poiché ogni chiave candidata è una singola colonna. Una tabella in 3NF significa che ogni colonna non chiave non dipende anche funzionalmente da qualche altra colonna non chiave e quindi crea una dipendenza transitiva. Non importa se ci sono una o cento chiavi candidate. In realtà è BCNF, non 3NF, che è la forma normale "finale" per quanto riguarda le dipendenze funzionali. Questo perché una tabella può essere in 3NF ma non essere in BCNF poiché potrebbero esserci più chiavi candidate che si sovrappongono. Pertanto, quando usiamo il termine 3NF per indicare "completamente normalizzato" rispetto alle dipendenze funzionali, ciò che realmente intendiamo è BCNF.
Se una tabella che indica una colonna ID con incremento automatico ha anche una colonna nota per essere univoca e non nulla, ad esempio un numero di previdenza sociale, questa colonna potrebbe essere utilizzata come chiave.
Non solo potrebbe essere, esso deve essere, se vogliamo garantire che i dati memorizzati nel database rimane coerente con le norme che abbiamo identificato nel mondo reale!
Ignorare i problemi pratici / aziendali (ad es. Rischio di sicurezza / privacy quando si passa a SSN come chiave / FK), da un aspetto strettamente progettuale dello schema, una tabella del genere non sarebbe in 3NF perché ci sono effettivamente 2 chiavi?
Come spiegato sopra, se la tabella è o meno in 3NF (o, soprattutto, BCNF) è ortogonale a quante chiavi candidate contiene.
La risposta varierebbe se esistesse una chiave univoca sull'altra colonna? Se è così, perché?
No, semplicemente perché determinare se la tabella è o non è in 3NF non ha nulla a che fare con quante chiavi candidate ha. Ha invece tutto a che fare con la garanzia che tutte le colonne non chiave siano completamente funzionalmente dipendenti da quelle chiavi candidate.
Ma questo fa emergere un punto interessante. Si noti che una chiave univoca quando definita come vincolo in un DBMS non è la stessa di un identificatore univoco definito come regola aziendale in un modello aziendale concettuale. Forse nel nostro mondo conosciamo sempre l'SSN della persona e quindi funge da chiave candidata per una persona, e forse introduciamo anche una chiave surrogata nello schema logico che chiamiamo ID persona . Il nostro modello di business include la regola che afferma che SSN è un identificatore univoco per una persona nel nostro mondo. Ciò implica una dipendenza funzionaledi tutti gli attributi descrittivi su questo attributo di identità. Questa regola non cambia solo perché ci siamo dimenticati o abbiamo scelto di non informare il DBMS. Questo è precisamente il motivo per cui è essenziale dichiarare il vincolo, in modo che il DBMS possa garantire che i dati memorizzati siano coerenti con le regole del modello di business! Se non abbiamo creato quel vincolo univoco su SSN, ora possiamo inavvertitamente creare più di una riga per la stessa persona con lo stesso SSN; ogni riga ha un ID persona diverso!
Un eccellente spunto su questi argomenti è la serie Practical Database Foundation di Fabian Pascal e la teoria del design e della relazione relazionale di Chris Date , da cui deriva questa risposta. Mentre ogni articolo di Fabian è un must, il documento n. 1 (che definisce chiaramente la differenza tra i livelli concettuale, logico e fisico) e il documento n. 4 (che definisce chiaramente i vari tipi di chiavi) affrontano specificamente questa domanda. Allo stesso modo, l'intero libro di Chris è assolutamente da leggere, mentre la Parte II è la sezione dedicata alla normalizzazione rispetto alla dipendenza funzionale.