PK autogenerate... amici o nemici? |
| Una doverosa precisazione |
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.
|
|
Perche' penso che sia male usarlo
|
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.
|
|
|
Quasi sempre c'e' una alternativa
|
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.
|
|
|
Aumenta il rischio di avere record inutili
|
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?
|
|
|
E' piu' complicato il reperire il valore dopo averlo creato
|
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.
|
|
|
Non puo' essere usato per ricerche veloci
|
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).
|
|
|
Un codice mnemonico e' piu' facile da usare
|
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.
|
|
|
Contro: la PK puo' diventare moooooolto lunga...
|
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...
|
|
|
Contro: le ricerche "parziali" diventano piu' lunghe
|
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.
|
|
|
Contro: le FK diventano molto complesse
|
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.
|
|
|
Contro: se cambio il valore di un campo si scassa tutto...
|
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.
|
|
|
Antonio Limone manda questo commento
|
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 Max length of comments: 1000 chars. |
8 commenti gufo_rosso dice il 10/04/2008 21:12: Esistono gli indici sui campi (unique, index) e anche su piu campi, la cosa di usare id autoincrement (usato dal db ssn usa) non e' quello di garantire unicita del dato ma la sua rapida elaborazione (il ssn italiano soffre dei problemi da te descritti "duplicazione"), gli id sono di piu facile gestione e passaggio di variabili da php Dissento. Il linguaggio di programmazione o il programma se ne fregano di quanto sono lunghe le chiavi, se parliamo di programmatore pigro e' un altro discorso Non permettono la modifica (ovvero NON vanno modificati) se cancelli il record. Le chiavi primarie non vanno mai modificate a prescindere da come sono fatte. Se hai un sistema che lo consente il sistema e' bacato. le relazioni a me sembrano piu facili a te. a me no il contro se devi recuprare una relazioni devi fare join (o theta) anche solo per un valore, se parlimo di clienti il campo univoco e' PIVA o CF il CF non e', non e' mai stato e mai sara' un valore univoco in caso di un magazzino hai il codice (che puo essere inventato da user, o autogenerato). un contro e' la dimensione degli indici su numero di record alto E chi se ne... della dimensione degli indici? Quello fa parte delle specifiche del software, inoltre, con i dischi fissi attuali, hai voglia a fare indici...
Luca dice il 16/08/2008 01:36: ciao Davide, ma il codice fiscale non esiste per definire univocamente un soggetto ai fini tributari? Per quale motivo dici che il cf non è univoco? Perche' non lo e', visto che puo' essere "calcolato" al momento. Il fatto che contenga il nome, cognome data e luogo di nascita della persona, non ne fa un buon candidato. In una citta' di una certa dimensione, ci sono troppe possibilita' che due persone con nome sufficientemente simile siano nate nello stesso giorno. Ceeeerto, puoi chiedere al ministero e yada yada yada... ma guardiamo in faccia la realta': chi lo fa? Lex dice il 23/08/2008 15:07: Il codice fiscale può essere sicuramente doppio, ad esempio per gli immigrati. I cittadini italiani hanno il codice del comune incorporato, gli immigrati, ai quali va COMUNQUE dato un cod. fisc. per la gestione dei contratti di lavoro, utilizzano il codice dello stato di provenienza. E' ovvio che in questo caso il cod. fis. non è univoco; per identificare un record in maniera univoca si utilizzano più campi. Per maggiori informazioni ecco qui il link: http://www.servizidemografici.interno.it/sitoCNSD/pagina.do?metodo=homeSettore&servizio=navigazione&codiceFunzione=PR&codiceSettore=IS
P.S. Paolo Brigati dice il 08/09/2008 12:14: Bella discussione, e trovo i pro e contro ben argomentati.. 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 dice il 11/09/2008 22:50: Sono in linea di massima d'accordo con te: l'uso di id autoincremento mi mette sempre a disagio.
In merito a chiavi composte da più campi, devo però aggiungere che lavorando con strumenti tipo Object/Relational mapping, la cruda realtà è che se vuoi tenerti le chiavi naturali (o business key, che fà più figo) devi faticare molto di più e alcune funzionalità ti sono precluse se non hai oggetti con un solo campo come chiave. il che mi fa pensare che usare tali strumenti dovrebbe venire per secondo, e come prima cosa dovrebbe esserci usare la propria testa.
Davide dice il 12/09/2008 10:08: > il che mi fa pensare che usare tali strumenti dovrebbe venire per secondo, e come prima cosa dovrebbe esserci usare la propria testa. Concordo, e chiaramente ognuno ha le proprie esperienze e le proprie preferenze sugli strumenti da usare. Personalmente, su applicativi di dimesioni medio grandi e con logiche un po' complesse ho visto ridursi e semplificarsi parecchio il mio codice (utilizzo in larga parte Java e lo strumento di cui parlo è Hibernate). Antonio dice il 23/09/2008 14:09: Grande Davide, come sempre. Anch'io avrei da dissentire riguardo al CF. D'accordo che non sia affidabile considerarlo univoco, de facto, ma solo perché viene "usato" male. Mi spiego, altrimenti sembra che stia dicendo idiozie. Sono quasi sicuro (al 99%, mi ri-documenterò) che SIA univoco, che solo l'Agenzia delle Entrate possa emanarlo, al che segue automaticamente che NON sia possibile autocalcolarlo. Chi lo fa commette un abuso, proprio perché il calcolo ti dà solo una "discreta" probabilità di avere un CF esatto. Lo sarà nella maggioranza dei casi. Ma quello esatto è proprio quello calcolato ed eventualmente corretto per evitare duplicazioni. Rimane che "di fatto" è meglio non usarlo, perché nemmeno le autorità competenti riescono a controllare i casi di duplicazione. Gabriele Paggi dice il 09/10/2008 10:43: Il CF italiano non è potenzialmente univoco: in caso di omocodia (wikipedia, alla voce omocodia, riporta che esistono 1400 nuovi casi di omocodia l'anno, per un totale di 24000) vengono sostituiti alcuni numeri, partendo da destra, con delle lettere, secondo una tabella predefinita, evitando così le collisioni (tra l'altro questi CF differenziati sono mal digeriti, per es., dal sito delle poste). Utilizzando tutte le combinazioni possibili di sostituzioni dei numeri con delle lettere, si possono generare al massimo 128 codici differenti...esaurite queste combinazioni avremo una collisione.Vista la possibilità che sia necessario variare uno o più numeri del CF per evitare omocodie, il calcolo "fai-da-te" del CF potrebbe non ritornare il giusto risultato...bastano due persone con nomi/cognomi simili e stessa data/luogo di nascita, che l'algoritmo che viene utilizzato da vari siti produca un risultato sbagliato. Add a comment (max 1000 chars)
|
| L'Autore |
Davide Bianchi,
works as Unix/Linux administrator for a "network security" company of Haarlem. Contacts: mail: davide AT onlyforfun.net , ICQ: 268751033, Jabber: davideyeahsure AT gmail.com Skype: davideyahsure |
| Contribuire | Volete contribuire? Leggete come! |
| Copyright | 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 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.
Ultimo aggiornamento: 11 Ottobre 2002