Domanda

Mi sto solo chiedendo quale sia la soluzione ottimale qui.

Supponi di avere un database normalizzato. La chiave primaria dell'intero sistema è un varchar. Quello che mi chiedo è: dovrei collegare questo varchar a un int per la normalizzazione o lasciarlo? È più semplice lasciarlo come varchar, ma potrebbe essere più ottimale

Ad esempio posso avere

People
======================
name      varchar(10)   
DoB       DateTime    
Height    int  

Phone_Number
======================
name      varchar(10)   
number    varchar(15)

O avrei potuto

People
======================
id        int Identity   
name      varchar(10)   
DoB       DateTime  
Height    int  

Phone_Number
======================
id        int   
number    varchar(15)  

Aggiungi ovviamente molte altre relazioni uno-a-molti.

Cosa ne pensate tutti? Quale è meglio e perché?

È stato utile?

Soluzione

Puoi davvero usare i nomi come chiavi primarie? Non esiste un rischio elevato per diverse persone con lo stesso nome?

Se sei davvero così fortunato che il tuo attributo name può essere usato come chiave primaria, allora - sicuramente - usalo. Spesso, però, dovrai inventarti qualcosa, come un customer_id, ecc.

E infine: " NAME " è una parola riservata in almeno un DBMS, quindi considera di usare qualcos'altro, ad es. fullname.

Altri suggerimenti

Credo che la maggior parte delle persone che hanno sviluppato applicazioni di database di dimensioni reali significative vi dirà che le chiavi surrogate sono l'unica soluzione realistica.
So che la comunità accademica non sarà d'accordo, ma questa è la differenza tra purezza teorica e praticità.

Qualsiasi query di dimensioni ragionevoli che deve eseguire join tra tabelle che utilizzano chiavi non surrogate in cui alcune tabelle hanno chiavi primarie composite diventa rapidamente non realizzabile.

L'uso di qualsiasi tipo di dati non sintetici (ovvero qualsiasi cosa proveniente dall'utente, al contrario di quello generato dall'applicazione) come PK è problematico; devi preoccuparti delle differenze di cultura / localizzazione, della distinzione tra maiuscole e minuscole (e di altri problemi a seconda delle regole di confronto dei DB), può causare problemi di dati se / quando i dati immessi dall'utente cambiano, ecc.

L'uso di dati non generati dall'utente (GUID sequenziali (o non sequenziali se il tuo DB non li supporta o non ti interessano le suddivisioni di pagina) o gli input di identità (se non hai bisogno di GUID)) è molto più facile e molto più sicuro.

Riguardo ai dati duplicati: non vedo come l'utilizzo di chiavi non sintetiche ti protegga da questo. Hai ancora problemi in cui l'utente inserisce " Bob Smith " anziché "Bob K. Smith" o " Smith, Bob " o "bob smith" ecc. La gestione della duplicazione è necessaria (e praticamente identica) indipendentemente dal fatto che la chiave sia sintetica o non sintetica, e le chiavi non sintetiche presentano una serie di altri potenziali problemi che le chiavi sintetiche evitano ordinatamente.

Molti progetti non devono preoccuparsene (scelte di confronto strettamente vincolate evitano molti di essi, per esempio), ma in generale preferisco le chiavi sintetiche. Questo non vuol dire che non puoi avere successo con le chiavi organiche, chiaramente puoi, ma per molti progetti non sono la scelta migliore.

Penso che se il tuo VARCHAR fosse più grande noteresti che stai duplicando un bel po 'di dati in tutto il database. Considerando che se hai scelto una colonna ID numerica, non stai duplicando quasi la stessa quantità di dati quando aggiungi colonne di chiave esterna ad altre tabelle.

Inoltre, i dati testuali sono una vera sofferenza in termini di confronti, la tua vita è molto più semplice quando stai facendo WHERE id = user_id rispetto a DOVE COME COME inputname ( o qualcosa di simile).

Se il " nome " campo è davvero appropriato come chiave primaria, quindi fallo. Il database non sarà più normalizzato creando una chiave surrogata in quel caso. Otterrai alcune stringhe duplicate per le chiavi esterne, ma questo non è un problema di normalizzazione, poiché il vincolo FK garantisce l'integrità delle stringhe proprio come farebbe con le chiavi surrogate.

Tuttavia non stai spiegando quale sia il "nome" " è. In pratica è molto raro che una stringa sia appropriata come chiave primaria. Se è il nome di una persona, non funzionerà come PK, poiché più di una persona può avere lo stesso nome, le persone possono cambiare nome e così via.

Una cosa che altri non sembrano aver menzionato è che i join sui campi int tendono a funzionare meglio dei join sui campi varchar.

E sicuramente userei sempre una chiave surrogata sull'uso dei nomi (di persone o aziende) perché non sono mai unici nel tempo. Nel nostro database, ad esempio, abbiamo 164 nomi con oltre 100 istanze con lo stesso nome. Ciò mostra chiaramente i pericoli legati alla considerazione dell'uso del nome come campo chiave.

La domanda originale non è di normalizzazione. Se si dispone di un database normalizzato, come indicato, non è necessario modificarlo per motivi di normalizzazione.

Ci sono davvero due problemi nella tua domanda. Il primo è se ints o varchars sia preferibile l'uso come chiavi primarie e chiavi esterne. Il secondo è se è possibile utilizzare le chiavi naturali fornite nella definizione del problema o se è necessario generare una chiave sintetica (chiave surrogata) per sostituire la chiave naturale.

Gli

??ints sono un po 'più concisi rispetto ai varchars e un po' più efficienti per cose come l'elaborazione dell'indice. Ma la differenza non è schiacciante. Probabilmente non dovresti prendere la tua decisione solo su questa base.

La domanda se la chiave naturale fornita funziona davvero come chiave naturale o meno è molto più significativa. Il problema dei duplicati in un "nome" colonna non è l'unico problema. C'è anche il problema di cosa succede quando una persona cambia il suo nome. Questo problema probabilmente non emerge nell'esempio che hai dato, ma emerge in molte altre applicazioni di database. Un esempio potrebbe essere la trascrizione in quattro anni di tutti i corsi seguiti da uno studente. Una donna potrebbe sposarsi e cambiare il suo nome nel corso di quattro anni, e ora sei bloccato.

O devi lasciare invariato il nome, nel qual caso non è più in accordo con il mondo reale, o aggiornarlo retroattivamente in tutti i corsi che la persona ha seguito, il che rende il database in disaccordo con i registri stampati realizzati in quel momento.

Se decidi su una chiave sintetica, ora devi decidere se l'applicazione sta per rivelare il valore della chiave sintetica alla comunità degli utenti. Questa è un'altra lattina di vermi, e oltre lo scopo di questa discussione.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top