PK autogenerate... amici o nemici?


Home Page | Commenti | Articoli | Faq | Documenti | Ricerca | Archivio | Storie dalla Sala Macchine | Contribuire | Imposta lingua:en it | Login/Register


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.


I commenti sono aggiunti quando e soprattutto se ho il tempo di guardarli e dopo aver eliminato le cagate, spam, tentativi di phishing et similia. Quindi non trattenete il respiro.

16 messaggi this document does not accept new posts

gufo_rosso

gufo_rosso Di gufo_rosso postato il 11/04/2008 08:17

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

Luca Di Luca postato il 16/08/2008 08:39

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

Lex Di Lex postato il 24/08/2008 13:30

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.
Naturalmente la progettazione è stata fatta con gli ID autogenerati (almeno così ho sentito)


Paolo  Brigati

Paolo Brigati Di Paolo Brigati postato il 08/09/2008 12:26

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

Davide Di Davide postato il 12/09/2008 08:30

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.
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

Davide Di Davide postato il 12/09/2008 10:27

> 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

Antonio Di Antonio postato 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

Gabriele Paggi Di Gabriele Paggi postato il 09/10/2008 11:25

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.

Diegoepoimaria

@ Gabriele Paggi Di Diegoepoimaria postato il 24/09/2012 12:16

Mio padre spesso racconta che, da giovane neolaureato, lavorò per qualche anno in una ditta chiamata Sogei, come programmatore, e li conobbe l'ideatore del codice fiscale, e spesso ne elogia i meriti e ne racconta le vicissitudini.

Il codice fiscale è univoco poichè è emesso , come hanno già detto, solo e soltanto dall'Agenzia delle Entrate.

Il motivo per cui fu scelto è che si voleva un codice che avesse una qualche attinenza con la realtà, e che potesse ricordare il nome della perosna interessata ... grave errore ...

Se si fosse scelto un codice NON ricostruibile, nessuno avrebbe pensato di crearselo da solo in caso di smarrimento del tesserino, e ne tantomeno ci sarebbero siti che "tentano" di calcolarlo, con metodi che possono anche ssere giusti, am che mancano dell'unico e fondamentale controllo: l' unicità.

In teoria è quindi giusto usare il codice fiscale, ma, in pratica, dal momento che esso viene inserito da utonti senza la minima cognizione di causa ( e senza la possibiltià alcuna di controllo sulla esattezza del codice, dato che l'Agenzia delle Entrate può modificare, cioè "sbagliare" ad hoc il codice ), concordo sul fatto che non sia giusto  usarlo come chiave primaria.

 

Per inciso: Ora capisco tutta la rottura di scatole di codice che il mio capo schiavista mi stà facendo scrivere per la gestione del DB ... :D

-- Diegoepoimaria

crwn

crwn Di crwn postato il 22/12/2008 14:08

Inoltre mi permetto di far rilevare che la corretta gestione del codice identificativo del Comune di nascita (se non ricordo male si chiama codice Belfiore?) è un bel problema di suo: ci sono un sacco di Comuni che sono stati soppressi/hanno cambiato nome/hanno più di un codice per motivi storici/ etc....
Il tutto è contenuto in qualche file excel o txt che dovrebbe essere reperibile in qualche sito di qualche ministero....
Con tutti questi condizionali avete già capito che problemi comporta gestire il tutto....

Anonymous coward

Di Anonymous coward postato il 29/01/2011 23:21

Se alla chiave primaria autogenerata si aggiunge una chiave univoca gestita dagli utonti (per capirci: quella che essi vedono ed usano per identificare l'elemento della tabella) si hanno a mio modo di vedere notevoli vantaggi, per esempio quello di poter adottare un criterio di codifica della chiave unica e poi avere un ripensamento senza per questo dover metter mano alla rifasatura delle dipendenze. Un esempio per chiarire: nel db ho i prodotti e le righe delle spedizioni dei medesimi; se la riga della spedizione fa riferimento al prodotto attraverso la chiave autogenerata, posso cambiare a piacimento il codice esterno (la chiave univoca) del prodotto senza perdere la relazione con le spedizioni avvenute.

 

-- Anonymous coward

Davide Bianchi

@ Anonymous coward Di Davide Bianchi postato il 30/01/2011 09:57

posso cambiare a piacimento il codice esterno


Questo puzza di cattiva progettazione/analisi lontano un kilometro. Perche' dovresti voler cambiare il codice esterno?


-- Davide Bianchi

Massimo M.

Di Massimo M. postato il 24/09/2012 21:33

Io nei miei db ho sempre usato una pk autoincrementante, usando poi, se necessario, le chiavi composte dai campi.

Per un semplice motivo: ho una tabella padre e una figlia, perche' nei programmi dovrei scrivere "select from figlia where campo1=pippo and campo2=pluto and campo3=paperino and....."

quando posso scrivere

select from figlia where idpadre=2?

una semplice pk autogenerata mi porta via pochissimo spazio, non e' pesante, non mi limita nell'avere chiavi composte da campi, e mi permette di accorciare le select e di non dovermi ricordare "la pk del padre e' codicearticolo+taglia+colore o codicearticolo+taglia+colore+ordine o ...."

 

per quanto riguarda il "una pk non puo' essere mai cambiata", beh, si quella e' la teoria, in pratica ho assistito a parecchi cambi di pk, del tipo da "codice+taglia" a "codice+taglia+colore". Vero, e' stato mal progettato dall'inizio, cio' non toglie che succeda.

-- Massimo M.

Davide Bianchi

@ Massimo M. Di Davide Bianchi postato il 25/09/2012 14:52

perche' nei programmi dovrei scrivere


Per lo stesso motivo per cui si usano variabili dal nome diverso da 'a' e 'b' e 'c'. Perche' IL CODICE DIVENTA PIU' LEGGIBILE e FACILMENTE MANTENIBILE! Perche' poi quando vai a rivedere la struttura capisci al volo cosa lega tabbela 'a' alla tabella 'b' (ed a tutte le altre).

-- Davide Bianchi

lufo88

Di lufo88 postato il 15/05/2013 20:06

Parlando di MySQL mi hanno spiegato che c'è un motivo per usare gli id autoincrementali (e usare UNIQUE su altri campi). A quanto pare essendo MySQL quello che è (una mezza fetecchia) Se gli aggiungi record con un ID autoincrementale come PK non deve rigenerare d'accapo l'indice sulla PK (cosa non vera con PK più "sensate").

-- lufo88

Rigongia

Di Rigongia postato il 08/03/2014 22:18

Solo una annotazione sul presunto contro del "se cambio la PK si scassa tutto" : anche su quella mezza fetecchia di MySQL esiste (quindi do per scontato che esista anche su sistemi un pelo piu' tosti) la possibilita' quando si definisce una chiave esterna di specificare cosa fare in caso di update o delete dei campi a cui quella chiave si riferisce. Ergo se cambio il valore della PK si smazza in automatico il DBMS ...

-- Rigongia

16 messaggi this document does not accept new posts

Precedente Successivo


Davide Bianchi, lavora come Unix/Linux System Administrator presso una societa' di Hosting in Olanda.

Volete contribuire? Leggete come!.
 
 

Il presente sito e' frutto del sudore della mia fronte (e delle mie dita), se siete interessati a ripubblicare uno degli articoli, documenti o qualunque altra cosa presente in questo sito per cortesia datemene comunicazione (o all'autore dell'articolo se non sono io), cosi' il giorno che faccio delle aggiunte potro' avvisarvi e magari mandarvi il testo aggiornato.


Questo sito era composto con VIM, ora e' composto con VIM ed il famosissimo CMS FdT.

Questo sito non e' ottimizzato per la visione con nessun browser particolare, ne' richiede l'uso di font particolari o risoluzioni speciali. Siete liberi di vederlo come vi pare e piace, o come disse qualcuno: "Finalmente uno dei POCHI siti che ancora funzionano con IE5 dentro Windows 3.1".

Web Interoperability Pleadge Support This Project
Powered By Gojira