Newsgroup: it.comp.software.database
Titolo: UUID come chiave primaria? [bozza]

Ciao a tutti, stavo buttando giù delle idee per un articoletto da mettere
sul mio sito. Il sito è su ColdFusion, ma quello su cui stavo ragionando è
quanto sia meglio creare delle chiavi primarie senza utilizzare le funzioni
del database utilizzato.
Sono graditi commenti sui pro e sui contro.
Grazie.
------------------
Solitamente la chiave primaria di una tabella viene creata utilizzando un 
campo auto incrementante. Questo può essere l’Autonumber di Mysql, il 
contatore di Access, oppure la sequence di Oracle e PostgreSQL.
Questo tipo di campi identifica un record in maniera univoca ed auto 
incrementandosi impedisce che due record possano avere la stessa chiave 
primaria. La chiave primaria però non deve essere obbligatoriamente un 
campo contatore o un numero intero, ma può anche essere una stringa, 
l’importante è che non ce ne sia un’altra uguale nella stessa tabella..
ColdFusion mette a disposizione la funzione CreateUUID() che ritorna una 
stringa di 35 caratteri nella forma di "XXXXXXXX-XXXX-XXXX-XXXXXXXXXXXXXXX"
dove "X" è un valore esadecimale (0-9 or A-F). E’ garantito che un UUID 
(Universally Unique Identifier) sia un valore unico e che non possa essere 
replicato richiamando la stessa funzione.
A questo punto possiamo decidere di usare UUID come chiave primaria delle 
nostre tabelle, con molti vantaggi ed alcuni inconvenienti.
Vantaggi
1) Maggiore portabilità tra database. Il bello di ColdFusion è che lo 
stesso codice può funzionare su sistemi operativi differenti e soprattutto 
ci consente di disinteressarci dei vari parametri che servono per gestire 
le connessioni al database. Il tag <cfquery> fa tutto il lavoro.
Quando però si porta un’applicazione da un database ad un altro i campi 
auto incrementanti possono creare dei problemi poiché ogni database li 
implementa in maniera diversa. Con UUID si elimina alla radice qualunque 
fonte di guai perché non utilizziamo le funzioni specifiche del database.
2) Recupero chiave primaria dell’ultimo record inserito. Secondo il 
database che usiamo occorre utilizzare una tecnica diversa. Ad esempio, con
Access possiamo fare una query per trovare il valore massimo (SELECT 
MAX(id_record)...), con PostgreSQL cercheremo il valore corrente della 
sequence (SELECT currval('sequence')...) etc. Utilizzando UUID conosciamo
in 
anticipo quale sarà il valore della chiave primaria e quindi lo stesso 
codice funzionerà su qualunque database.
Es:
<cfset id_record = createUUID()>
<cfquery>
INSERT INTO tabella (id_record, testo) VALUES ('#id_record#','#testo#')
</cfquery>
3) Impedire inserimenti multipli dallo stesso form. Per impedire che 
l’utente invii lo stesso form più volte si possono usare vari accorgimenti,
ma con UUID il sistema è semplificato. Nel form d’inserimento si mette un 
campo hidden che contiene l’UUID da utilizzare come chiave primaria per il 
nuovo record da inserire. Prima di inserirlo si controlla che l’UUID non 
sia già stato usato. Se l’UUID è già stato inserito vuol dire che lo stesso
form è stato inviato due volte e quindi interrompiamo la procedura.
4)Sincronizzazione tra database di sviluppo e database di produzione. 
Spesso vogliamo tenere sincronizzati i due database, ma allo stesso tempo 
desideriamo inserire dei dati di prova nel database di sviluppo. Altre 
volte capita che dobbiamo trasferire i dati dal database di produzione a 
quello di sviluppo, in modo da fare i test più tranquillamente. Se 
utilizziamo i campi contatore o le sequence occorre stare molto attenti 
perché la chiave primaria può essere già stata utilizzata. Con UUID non 
corriamo il rischio di conflitti.
5)Ogni record dell’intero database ha una chiave primaria univoca. Tutti i 
record del database sono distinti uno dall’altro anche se sono in tabelle 
differenti. Per alcune applicazioni può essere un grosso vantaggio, 
soprattutto quando si sviluppa un sistema con una sofisticata gestione dei 
permessi.
6)Unione di più tabelle. Se dobbiamo unire tra loro più tabelle, magari di 
database differenti, con UUID ci garantiamo che non si verifichino 
violazioni della chiave primaria.
Svantaggi
1)Maggiore lentezza. Con chiavi primarie numeriche i database riescono ad 
indicizzare e recuperare i record più velocemente.
2)Difficoltà nel sistemare le cose a mano. Se occorre sistemare relazioni 
tra tabelle corrotte o comunque intervenire direttamente sul database, i 
campi numerici auto incrementanti sono certamente più facili da gestire.
3)Problemi con nextRecord. Quando implementiamo un sistema per scorrere i 
vari record uno ad uno, tipo le maschere di Access, generalmente ci 
appoggiamo al campo contatore. Ad esempio se dobbiamo andare al record 
successivo faremo una query di questo tipo:
<cfquery name="mia_query" maxrows=1>
SELECT 
WHERE  id_record > #id_record#
ORDER BY id_record
</cfquery>
Utilizzando UUID questo sistema salta, a meno di non lasciare un campo 
contatore da utilizzare per questi scopi.
4)Url molto lunghe. Gli ID dei record sono spesso passati attraverso l’URL.
UUID crea delle chiavi primarie molto lunghe, di ben 35 caratteri. Quando 
per visualizzare una pagina dobbiamo utilizzare molti parametri, si può 
correre il rischio di creare delle URL che il browser non è in grado di 
gestire. Non esiste un limite di lunghezza di una URL però si deve tenere 
conto che alcuni browser non riescono a gestire URL più lunghe di 240 
caratteri.
Faser
--------------------
FABIO SERRA
*Questo testo deve essere valutato secondo il senso della RFC-3*
Per rispondere in e-mail sostituire "invalid" con "faser"
http://www.cfmentor.com
--------------------

 del database utilizzato.
Se la chiave primaria la crei tu (in modo controllato), sei in grado
di usarla come chiave di ricerca, in caso contrario dovrai diventare
matto a reperirla quando vuoi inserire record correlati (madre/figlia).
Davide

 più lunghe di 240 caratteri.
puoi usare post anziché get come metodo del form... non dovrebbe dare
problemi con l'url. (magari sbaglio) 
per quel che mi riguarda, credo che prima di iniziare a sviluppare, sia
necessario valutare bene il db su cui appoggiare. questo perché l'id
sequenziale è solo una delle 1000 difficoltà che si incontrerebbero a
migrare di db. vedi per esempio i vari linguaggi procedurali e triggers
che non tutti supportano, viste di sistema, gestione dei grants,
addirittura viste vere e proprie... quindi il problema non si risolve con
un UUID che, per quanto univoco che sia, presto o tardi dovrà
ripetersi... almeno una volta nel mondo! 
se si decide a questo punto di tenere una struttura più semplice
possibile (senza nested queries, senza stored procedures, senza niente
che non sia assolutamente compatibile con tutti i db, per esempio le
foreign keys) allora il problema dell'id passa in secondo piano, visto
che per l'id, al di fuori della definizione nella create table, è
concettualmente uguale per tutti i db. 
ma così si rischia di pagare milionate per la licenza del dbms e poi non 
sfruttarne le potenzialità...
ciao



Giusto, bisogna tenere presente anche questo.
Ciao.


sfruttarne le potenzialità...
Si usano quelli free :-) No, scherzi a parte concordo su tutto quello che
hai detto, anzi ti ringrazio per la risposta esauriente. Diciamo che non
sto nè da una parte nè dall'altra, sto solo valutando pro e contro. L'idea
mi nasceva dal fatto che sviluppando applicazioni web, spesso si usando db
diversi, ma l'applicazione è più o meno la stessa. Certo la chiave primaria
non è l'unica differenza però sono tante piccole cose che alla fine ti
fanno raddoppiare il lavoro. Inoltre è vero che l'ID concettualmente è
uguale a tutti i db, ma viene implementato in modo diverso.
Il dilemma che hai prospettato ce l'ho anche io. Non so mai se utilizzare
appieno il db o stare su un SQL "standard". Generalmente guardo che tipo di
sito si sta facendo. Se è una cosa grossa in housing o un'intranet con dati
presistenti si presume che il db non cambierà, se è una cosa che parte da
zero e piccola, magari con Mysql cerco di stare sullo standard.
Il problema è che mi è capitato di dover passare da Access a Mysql a
Postgres :-(
Ciao.


 stare sullo standard. 
allora sì, ma se il sito è per esempio gestionale e si spalma su centinaia 
di tabelle tutte legate tra loro...
le foreign keys e triggers diventano più che vitali!
ciao

le foreign keys e triggers diventano piů che vitali!
Concordo, č per questo che maledico la diffusione di Mysql :-)
