Auto-generated Primary Keys, friends or foes? |
|
Ci tengo a precisare che quello che segue e' la MIA personale opinione, maturata dopo 15 anni passati a sviluppare, mantenere, debuggare e lavorare su un vario numero di sistemi basati su vari databases. Se non siete d'accordo con me, per cortesia mandatemi una mail con le vostre opinioni ed io le aggiungero' in coda in modo da avere una esposizione completa dei pro e dei contro. NOTA: non e' detto a priori che pubblichi la vostra mail, lo faro' solo se reputero' le vostre argomentazioni sufficientemente logiche e non gia' trattate in questo documento. Premetto che non penso che gli ID autogenerati siano negativi in senso assoluto. In alcuni casi non c'e' proprio nessuna altra scelta. Quello che non mi trova d'accordo e' il loro uso sempre e comunque, anche quando una scelta alternativa e' disponibile. Nel 98% dei casi che mi sono ritrovato davanti in cui una tabella aveva un'ID autogenerato vi erano un numero sufficiente di campi univoci da produrre un'ottima chiave non-autogenerata per la tabella stessa. Questo ha molto a che fare con una pessima (o nessuna) progettazione del database. In molti casi vedo tabelle con 10 campi di cui 9 accettano NULL e l'unico campo non-null e' l'ID. Se un campo puo' essere nullo le possibilita' che sia sempre nullo sono altissime. In tal caso e' meglio eliminare del tutto il campo. In teoria ogni campo di una tabella dovrebbe essere riempito con un valore valido (aka: non desumibile dal valore di altri campi) prima della de-normalizzazione. Se l'unico campo valido in una tabella e' l'ID, la possibilita' di ritrovarsi con 'n' record identici (salvo l'ID) aumenta. E tali record sono assolutamente inutili, un utente non e' in grado di distinguerli (e come potrebbe?), ne' di gestirli, l'intera struttura dati inizia a perdere di validita' e tutte le informazioni diventano sospette o inutili. Immaginiamo un sistema di fatturazione in cui (causa un baco di progettazione e/o di implementazione) lo stesso "cliente" e' stato inserito 10 volte. Abbiamo 10 fatture, quale e' il fatturato totale del cliente? Ma e' sempre lo stesso cliente o sono 10 clienti diversi che "sembrano" lo stesso? Il cliente telefona e chiede informazioni riguardo una fattura... troveremo la fattura o finiremo per dirgli che "tale fattura non esiste?" Che succede se arriva un controllo della finanza? Alcuni database consentono la generazione del valore indipendentemente dall'inserimento o meno del record, altri invece collegano la generazione con l'inserimento, in questo secondo caso il reperire il valore e' piuttosto complesso e dipende dalle capacita' del RDBMS e del sistema che si sta' usando per inserire i dati. Se la PK e' data dai valori del record, la avete prima ancora dell'insert in ogni caso. Riprendendo l'esempio di prima del sistema di fatturazione, per ricercare un cliente non si puo' utilizzare l'ID perche' tale ID non ha senso e l'utente non lo conosce, dovra' pertanto usare o una ricerca alfabetica o altro sistema, rallentando la ricerca e rischiando di ricevere piu' dati di quello che si cerca (un solo cliente). L'utente potrebbe anche non essere in grado di distinguere il cliente "giusto" una volta trovato nel sistema in mezzo agli altri "simili". Supponendo invece che l'ID sia composto da informazioni che l'utente conosce, e' possibile sveltire le ricerche e le possibilita' di reperire piu' record si riducono. L'utente e' in grado di distinguere i singoli record perche' conosce le informazioni (le ha inserite lui). Avendo lavorato presso una grossa societa' di distribuzione, posso dire con certezza che forzare gli utenti ad inventarsi un sistema di classificazione da' i suoi frutti. Dopo una settimana tutti erano in grado di recitare senza errori meta' dei codici senza doverli nemmeno ricercare. I codici errati venivano individuati senza sforzo e le ricerche (nonostante la non eccelsa velocita' dell'hardware) erano rapide e ritornavano sempre il risultato voluto. E non e' che il database fosse piccolo (175.000 articoli). Viceversa, in una seconda societa' e con un sistema molto piu' piccolo, la presenza di ID autogenerati ha portato rapidamente ad una esplosione di record 'n'-uplicati. Dopo meno di 6 mesi l'anagrafica clienti contava 273.000 record (e rotti), mentre i clienti "effettivi" erano meno di 20.000. Qui' il problema non era solo la pessima progettazione del sistema, ma anche la pessima realizzazione che impediva delle ricerche valide, per cui l'utente finiva con il re-inserire il cliente in quanto non riusciva piu' a ritrovarlo. In alcuni casi l'unico modo di avere una PK per una tabella e' mettere tutti i campi in sequenza. A questo punto conviene (se il database lo consente) passare ad una Index Organized Table, ovviamente pagandone lo scotto... La mia opinione comunque e' che la PK in molti casi se la deve gestire il computer, quindi quanto essa sia lunga non e' che faccia una grande differenza. Vero, ma in molti casi lo scopo di una ricerca parziale e' "perche' non mi ricordo esattamente...". Lo scopo di una PK mnemonica e' evitare le ricerche parziali il piu' possibile.
Vero anche questo. Se la PK di una tabella e' composta da 7 campi, gli stessi devono essere nelle tabelle collegate per poter referenziare la precedente. Questo e' uno degli argomenti piu' a favore di ID autogenerati (un solo campo da riportare). Il pro in questo caso e' che nel 90% dei casi una interrogazione sulla tabella "figlia" non deve necessariamente fare una Join sulla tabella "madre" per recuperare quei 7 campi, e se quei 7 campi sono gli unici che interessano, non serve fare una Join ma basta una query su una tabella singola. Questo non ha senso. La teoria dice che non si possono modificare le PK. Se avete progettato un sistema che vi consente di cambiare le PK vi conviene assicurarvi di riportare i cambiamenti sulle tabelle collegate o cambiare mestiere.
Dove lavoro usano delle chiavi che definiscono "parlanti".
Per fare un esempio il codice cliente e' un char(9) nella forma: 200xxyyyy
dove le y sono autogenerate (valori fra '0000' e '9999') e i valori xx
assumono i valori '02' per clienti italiani e '03' per clienti esteri.
Problema: aggiungiamo una nuova categoria e la chiamiamo '05'(???)
Lo abbiamo fatto ma abbiamo dovuto controllare tutti i report sui clienti
(per non parlare di un altro paio di cosette). Poi ogni tanto inseriscono un
cliente nella categoria '05' mentre in realta' non lo era.
Cosi' se il cliente e' appena stato inserito lo cancelliamo noi (gli utenti
non possono cancellare nulla) altrimenti viene fuori un casino: chi ha fatto
il DB ha pensato bene di non usare PK e FK quindi di modificare il valore di
una PK non se ne parla neppure...
PS: non ho mai capito a cosa serve il prefisso '200'...
Da quello che dici mi pare evidente che il problema qui' non sono i codici in se', ma il modo come il sistema e' stato progettato. Le chiavi "parlanti" non mi sembrano molto "parlanti". Ovviamente, una cattiva progettazione del sistema non puo' essere risolta da una PK autogenerata o meno. |
Comments are added when and more important if I have the time to review them and after removing Spam, Crap, Phishing and the like. So don't hold your breath. And if your comment doesn't appear, is probably becuase it wasn't worth it.
Luca
By Luca - posted 16/08/2008 08:39
- reply
Lex
By Lex - posted 24/08/2008 13:30
- reply
Naturalmente la progettazione è stata fatta con gli ID autogenerati (almeno cosė ho sentito)
Paolo Brigati
By Paolo Brigati - posted 08/09/2008 12:26
- reply
solo un dubbio, per il discorso univocita' cod. fiscale.
A quanto ne so', l'ultimo carattere, il 16° di controllo e' usato anche per evitare doppioni, venendo cambiato in caso un C.F. identico esista gia' rispetto a quello in emissione....o sbaglio?
il fatto che il CF possa essere auto-calcolato e che le uniche informazioni che contiene siano il nome, cognome, data e luogo di nascita ne fanno, per definizione, un codice NON-univoco. Puo' darsi che, se tu informi l'ufficio competente, quelli possano cambiarlo, ma per informare l'ufficio, devi sapere che il codice e' non-univoco. Se il codice fosse progettato per essere univico, non potresti autocalcolarlo. Quindi assumere che tale codice sia univoco e' sempre e comunque un errore
Davide
By Davide - posted 12/09/2008 08:30
- reply
Questa cosa mi fa pensare che chi scrive questi ORM è bravissimo nella programmazione ma ha un'idea di database un po' particolare.
il che mi fa pensare che usare tali strumenti dovrebbe venire per secondo, e come prima cosa dovrebbe esserci usare la propria testa.
Davide
By Davide - posted 12/09/2008 10:27
- reply
Antonio
By Antonio - posted 23/09/2008 14:09
- reply
Gabriele Paggi
By Gabriele Paggi - posted 09/10/2008 11:25
- reply
crwn
By crwn - posted 22/12/2008 14:08
- reply
Davide Bianchi, works as Unix/Linux administrator for a "network security" company of Haarlem. Contacts: mail: davide AT onlyforfun.net , Jabber: davideyeahsure AT gmail.com
Do you want to contribute?
read how.
This site is made by me with blood, sweat and gunpowder, if you want to republish or redistribute any part of it, please drop me (or the author of the article if is not me) a mail.
This site was composed with VIM, now is composed with VIM and the (in)famous CMS FdT.
This site isn't optimized for vision with any specific browser, nor
it requires special fonts or resolution.
You're free to see it as you wish.