posts - 640, comments - 2599, trackbacks - 144

My Links

News

Raffaele Rialdi website

Su questo sito si trovano i miei articoli, esempi, snippet, tools, etc.

Archives

Post Categories

Image Galleries

Blogs

Links

Un motivo in più per usare i Guid come chiavi primarie

Delle volte leggere Connect è istruttivo. Prendiamo questo bug feedback che riguarda SQL 2005-2008:

https://connect.microsoft.com/SQLServer/feedback/ViewFeedback.aspx?FeedbackID=328811

"Yes, it's a bug - whenever a parallel query plan is generated @@IDENTITY and SCOPE_IDENTITY() are not being updated consistenly and can't be relied upon". E più sotto "we can't fix this for SQL 2008."

A questo commento di Microsoft seguono alcuni workaround. Ad ogni modo lintero feedback è decisamente istruttivo.

Per la serie "vivi più tranquillo e usa un bel Guid se non in casi tutti da valutare".

Print | posted on lunedì 22 dicembre 2008 22.38 |

Feedback

Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Lo sai che con un post del genere scateni la polemica! :-D
Anyway vorrei proprio vedere ogni quanto avviene la pressione del tasto save allo stesso istante su una nuova istanza di una identita', sulla stessa tabella ...
23/12/2008 5.43 | raffaeu
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Capisco il problema ma non condivido la soluzione.
Usare un GUID significa usare una chiave che occupa 4 volte tanto lo spazio di un INT. Spesso la primary key è usata anche come indice clustered (visto che è il default) e ciò ha come conseguenza quella di propagare il GUID in tutti gli indici secondari. L'efficienza cala e la cosa è sensibile in database un po' grandi. E sicuramente il problema dei conflitti non ce l'hai in un database piccolo.
Quando ho avuto altri problemi sull'uso di IDENTITY, la soluzione è stata generare la chiave all'esterno piuttosto che farla generare a SQL Server...

Marco
23/12/2008 8.26 | Marco Russo
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Macché polemiche, siamo tutti maggiorenni, quindi basta leggere (e di materiale ce n'è fin troppo) e decidere se morire di int a 64 bit o di guid a 128 bit.
Considerato poi che sulla "cloud" i db relazionali non esistono e i guid sono un must, eccotene un altro di buon motivo.

Purtroppo la contemporaneità che credi che sia così improbabile io l'ho già vista. Prova ad usare @@Identity al posto di @@scope_identity e ti accorgi presto di avere in mano un int che non è il tuo, anche in un ambiente non enterprise.
23/12/2008 8.28 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Marco, non sto dicendo che sia da usare solo il Guid, ma sinceramente preferisco sprecare un po' di spazio piuttosto che complicare la logica di gestione.
Oggi i tera non costano, mentre lo sviluppatore (e i suoi errori) si.
Il Guid rende tutto terribilmente più semplice e se non ci sono casi particolari è decisamente più conveniente.
Mettiamola così. Se scopri che ci sono dei problemi di performance passare da un Guid ad un int è indolore. Il contrario non è altrettanto banale.
In pratica se parti da un int stai facendo premature optimization.
23/12/2008 8.32 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Non mi convinci :)
Su un Data Mart, non dobbiamo neanche discuterne perché la penalizzazione del GUID è troppo forte.
Su un database "normale", prima di usare un int64 devi avere più di due miliardi di righe in una tabella, il che limita molto i casi in cui ciò sia necessario. Il problema non è lo spazio su disco, quanto l'efficienza nell'uso dell'I/O e nell'uso della cache. La chiave che usi su un indice clustered in SQL Server è un fattore leva che agisce su tutti gli indici, quindi stai esercitando una leva su tutta la dimensione della tabella.
Non metto in dubbio che ci siano scenari in cui l'uso del GUID sia consigliabile (e quando serve va usato). Ma l'uso generalizzato del GUID come chiave primaria di qualsiasi tabella (occhio, ho detto tabella, non ho detto entità) lo vedo pericoloso, così come è pericoloso usare indiscriminatamente INT IDENTITY anche quando esiste una chiave primaria naturale nell'entità.
Quello che dunque non condivido è il suggerimento di usare indiscriminatamente i GUID per qualsiasi tabella. Io non dico di usare sempre INT IDENTITY, io dico di pensare a quello che si sta facendo valutandone le conseguenze. Per esempio, un GUID, prestazionalmente parlando, se usato come indice clustered dà luogo a effetti di frammentazione e page split che vanno al di là del semplice problema dell'occupazione di spazio, tanto per fare un esempio. E questi effetti sono tanto più significativi quanto più è grande la tabella.

Marco
23/12/2008 9.05 | Marco Russo
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Marco
Tu dici: "Quello che dunque non condivido è il suggerimento di usare indiscriminatamente i GUID per qualsiasi tabella"
Neppure io! Il titolo del post è "Un motivo in più ...". E nel commento precedente dico "non sto dicendo che sia da usare solo il Guid"".

Certamente preferisco l'uso di un guid prima di un int, ma le scelte alla cieca non fanno per me :)
Più volte mi è capitato di vedere il cliente che accetta di vedere se sul db ci sono problemi macroscopici ma rinuncia a spendere in ottimizzazioni preferendo spendere in hardware o investire nello sviluppo di codice che risparmi gli accessi su db.
Tu mi potrai trovare dozzine di casi in cui il Guid ti penalizza. Io te ne trovo altrettanti in cui posso minimizzare il problema nell'application server. Alla fine ci mettiamo a discutere di architettura e non se ne esce più.
Ripeto: non sarà una soluzione universale, ma IMHO è certamente preferibile se non in casi particolari.
Poi ciascuno tragga le sue conclusioni dai nostri commenti :)
23/12/2008 9.16 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Raf,
onestamente mi interessa fino ad un certo punto stare qui a discutere le tue posizioni, che ovviamente non condivido.
Il fatto è che le parole hanno un peso e che questa pagina, come quella dell'altro giorno su SQL CE, possono essere lette da persone che magari non hanno gli strumenti per poter analizzare a fondo i vantaggi e gli svantaggi di una teoria esposta parzialmente e superficialmente come hai fatto tu nel tuo post originale.
Il sito di Ugidotnet è preso come riferimento da moltissime persone di tipologie diverse, non solo super esperti, e credo che sia responsabilità delle figure più in vista della community l'avere un minimo di attenzione nel come i messaggi vengono dati, evitando il rischio che io chiamo "sindrome da Studio Aperto" per come vengono date talvolta certe notizie. Non sto parlando di censura o altro, ma solo di attenzione alle parole e ai vari aspetti del problema che si affronta.
Parlando di IT e di sviluppo software, il "vecchio" maestro Antonio Sponza ci ha sempre insegnato che siamo tipicamente in un sistema chiuso, e che ogni direzione che viene presa avrà dei pro e dei contro in termini di vantaggi e svantaggi complessivi. Anche questo caso mi sembra che rientri pienamente in quel contesto e così dovrebbe essere trattato.
Vedo che Marco ci ha provato a riportare il discorso su binari corretti ma senza successo.
Voglio solo ricordarti di spiegare ai clienti di cui parli che alle volte spendere in Hw molto spesso non risolve i problemi di performance, ci sono colli di bottiglia (es. in caso di locking su pagine dati o indici) che non potrà evitare nemmeno con un server monstre.

Lascio a chi legge qualche puntatore utile ad approfondire l'argomento, così potrà veramente trarre delle conclusioni:
www.sql-server-performance.com/.../...ance_p1.aspx
www.sqlmag.com/.../sql_server_46821.html
www.informit.com/articles/article.aspx?p=25862
23/12/2008 10.27 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Silvano, forse il mio italiano non mi è chiaro ma quando scrivo "un motivo in più..." non mi sembra che sto dicendo di usare sempre e solo il guid.

Inoltre i pro e i contro sono stati stra-discussi in tantissime sedi, mio blog compreso e basta buttare una qualsiasi ricerca in rete per trovare dozzine di articoli che analizzano le due soluzioni. Non mi sembra proprio che il post abbia il senso di porre "una parola definitiva" su alcunché.

Rigetto l'accusa di sindrome da "studio aperto":
- Il bug di SQL Compact è devastante e mi ha fatto girare le xxx non tanto per il bug di per se ma per la totale indifferenza rispetto alla gestione del versioning da parte del team di sql server. (Per aggiungerne un altra, vedi il management studio di 2008, l'unica a poter gestire Compact SQL, quando ancora la 2008 non era neppure uscita)
- Il bug che ho riportato in questo post va conosciuto perché se sai di aver scritto query di quel tipo, è necessario prendere i provvedimenti PRIMA che scoppi tutto.

Io direi piuttosto sindrome da "conoscenza".

Infine detesto il talebanesimo. A me piace la tecnologia e i miei giudizi prescindono dal fatto che sia targata "Microsoft". Se mi scaldo quando qualcuno parla a sproposito di Vista, non posso che incavolarmi quando ci sono toppate dall'altra parte.
Se omettessi critiche solo perché SQL Server è Microsoft, beh sarebbe proprio penoso.
23/12/2008 11.22 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

A me non me ne frega niente di Microsoft o non Microsoft.
Scrivere "il bug di SQL Compact è devastante" E' TALEBANESIMO e non capisco come tu faccia a non accorgertene!!
Devastante per chi??? Hai trovato tutti questi post in giro sulla rete che parlano di "corruzione dei dati" in SQL CR?
Magari non sarà il pezzo di tecnologia più usato al mondo, ma qualche decina di migliaia di sviluppatori lo usano e non ho mai letto nulla del genere, chissà come mai... forse perchè chi scrive le query lo fa usando correttamente i parametri nominali oppure rispettando la sequenza della colonne nelle tabelle?
Ho forse detto che non se ne deve parlare?? Certo che no, ma "Per la serie "vivi più tranquillo e usa un bel Guid se non in casi tutti da valutare" o "corruzione dei dati" li ho forse scritti io??
Beh, sono entrambe frasi sbagliate, e non si tratta di omettere nulla su SQL Server o Microsoft, ma solo di essere obiettivi.
Ribadisco il punto, non stiamo parlando di censura ma di RESPONSABILITA' nei confronti di chi si fida di quello che legge qui sopra. Dovrebbe esserci anche questo nel bagaglio di un MVP o di un leader di una community, no?
23/12/2008 11.46 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Io sto usando (dopo un travagliato processo decisionale) i GUID proposti nell'articolo su informit, con le ultime cifre generate in modo sequenziale. Mi sembra un buon compromesso. D'altra parte, per generare le chiavi nella logica applicativa, non vedo molte alternative... Una generazione sequenziale pone sempre problemi di concorrenza. Si può poi disquisire se serva o meno avere le chiavi prima che i dati vengano persistiti sul database. Secondo me, in scenari disconnessi, può fare comodo. Dipende, in ogni caso, dalla situazione.
23/12/2008 11.49 | Andrea
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Andrea,
credo che tu abbia colto nel segno, i GUID sono nati infatti proprio per supportare scenari disconnessi e distribuiti, pensiamo alla motore delle Repliche che ne fa uso in alcune condizioni. I GUID consentono ovviamente di avere una univocità che può essere molto interessante per supportare la logica applicativa, ma questo non significa che debbano per forza essere usati come chiave, con le implicazioni che questo comporta. Questo approccio consente per esempio di risolvere l'annoso problema del dover conoscere nel middle-tier a tutti i costi il valore della chiave (logica o surrogata) che verrà utilizzata nel db. Risolverà sempre e comunque tutti gli scenari? Forse no, ma dare una occhiata a come funzionano certi meccanismi distribuiti (come le repliche, ad esempio) è molto utile per trarre degli insegnamenti utili su cosa fare e non fare.
23/12/2008 12.02 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Silvano. Quando scrivi due colonne string e le due colonne vanno uno al posto di un altra, i dati sono da buttare, aka *corrotti*.

È inutile che ti scaldi perché il bug c'è, è riconosciuto, e viene corretto con la SP1. Se la SP1 faccia la patch sull'engine o sul provider non lo so e ripeto che non è rilevante. Quando la macchina non funziona te ne frega proprio niente se sia la centralina o l'iniettore.

Questo non è talebanesimo, è solo dire le cose come stanno e nel post ho scritto che i named parameters sono certamente la soluzione.
Per tua conoscenza il problema non è solo quello. La *SP0* caccia fuori SQLException a raffica anche usando i named parameters. Messa la SP1, tutto torna a funzionare, mah.

Visto che fai il criticone, ecco il perché dei "?". Il data layer è nato e testato su PC con i named parameters e ho dovuto migrarlo ai "?" perché una vecchia versione di SQL CE non li supportava. Non ricordo quale versione fosse, forse la versione precedente a SQL Mobile, ma questo è quanto.
Messo in produzione funzionava tutto ma NON vai a migrare del codice che funziona da 3 anni senza problemi solo perché stai aggiornando (obbligato dal fatto che SQLCE non supporta il side-by-side) alla versione nuova del db.

Guid. Io sono pro-guid... posso scriverlo in un MIO post? Ho detto "IO" non ho detto "chi non lo usa è un fesso". Ma porca la miseria, chi è qui il talebano?????
23/12/2008 12.08 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Mah, lasciamo perdere tanto non serve a niente.
Hai ragione tu, giudicherà chi legge... e spero che chi deve leggere finalmente inizi a farlo!
23/12/2008 12.16 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

"vivi più tranquillo e usa un bel Guid se non in casi tutti da valutare".

Raf il bug è di Febbraio 2008 e da allora ha ricevuto pochissimi feedback. Puoi facilmente immaginare il perchè. Il bug si verifica solo in presenza di piani paralleli che come certamente saprai, dato che parli della cosa, dovrebbero essere praticamente assenti da un database OLTP, visto che la loro presenza segnala normalmente l'assenza di indici corretti. Il bug è comunque correggibile tramite un work-around, (MAXDOP 1) quindi è inutile cercare di far tanto rumore per nulla. O forse vuoi aumentare il numero di lettori del tuo blog con post sensazionalisitici? Sinceramente, non capisco perchè fare dell'inutile allarmismo....

"Prova ad usare @@Identity al posto di @@scope_identity e ti accorgi presto di avere in mano un int che non è il tuo, anche in un ambiente non enterprise. "
Ancora una volta, ogni persona che lavora con SQL Server sa bene che @@Identity può restituire un valore diverso dall'identità inserita nella tabella, qualora si faccia uso di trigger. Per tale motivo ne è sconsigliato l'utilizzo e quindi si usa SCOPE_IDENTITY() che restituisce l'identity generato per la tabella nello scope del codice che chiama la funzione.
Non si capisce quindi l'utilità della tua affermazione.

"Oggi i tera non costano, mentre lo sviluppatore (e i suoi errori) si."
Come ben sai ogni DB utilizza memoria cache, che ad oggi non si misura in tera. Sul fatto che gli errori di uno sviluppatore costino non c'è dubbio. Costa però molto di più l'errore di un "architetto", visto che inficiandone il design mina la soluzione alla sue fondamenta. Ed un design sbagliato per un DB è una cosa che ti porti dietro per molto tempo e COSTA MOLTO NEL TEMPO A VENIRE.
24/12/2008 0.45 | Davide Mauri
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

"Alla fine ci mettiamo a discutere di architettura e non se ne esce più."
Vero. Rimaniamo sul problema tecnico. Ho appena fatto un posto che fa chiarezza in merito:

community.ugiss.org/.../...-guid-pro-e-contro.aspx

Peccato però che tu esordisca il tuo post dicendo "vivi più tranquillo e usa un bel Guid se non in casi tutti da valutare". IMHO veramente deprecabile: per risolvere un problema tecnico (che in realtà ha gia delle soluzioni) sei disposto a trovare una soluzione architetturale (l'uso di GUID quando a priori quando non ce n'è esplicito bisogno) e quindi a minare le performance di un database ed innalzarne i suoi costi di manutenzione, aumentando altresi i costi relativi all'ottimizzazione per tutto il tempo a venire....IMHO è una cosa veramente discutibile.

"Io direi piuttosto sindrome da "conoscenza"."
Si, però per una conoscenza corretta ci vogliono anche i supporti tecnici corretti. In altri termini le prove. Nel post menzionato in precedenza ho analizzato a fondo il tema dei GUID (sempre da un punto di vista tecnico) e quindi ora se ne possono trarre le conclusioni. Mi sarei aspettato un confronto simile in una discussione di questo genere, con dei riferimenti precisi. Dire "che si trovano su internet" equivale a non dire nulla. Il post cmq ora c'è lo si può usare come riferimento. Detto ciò, diventa chiaro che dire semplicemente "meglio il GUID" dicendo che tanto "l'hardware" non costa è semplicemente errato. Su che basi lo si sostiene? Sono state fatte delle ricerche pubbliche? Senza non è possibile costruire un confronto serio, e quindi permettimi di dubitiare della tua tesi: sarei curioso di vedere se un upgrade hardware che tiene conto anche dei costi di licenza (non è che tutti hanno le licenze Enterprise....chi ha la Standard deve fare i conti con dei limiti molto più stringenti), delle giornate uomo necessarie per installare e configurare S.O. ed applicativi sia veramente cosi conveniente. Magari in piccole (molto piccole) realtà si, in medio grandi non credo proprio. Anche perchè questo non significherebbe risolvere il problema, ma semplicemente spostarlo un pò più in là. Soluzione politica che mal si addice ad un tecnico, ma che può cmq essere valida, a patto di aver costi e benifici a disposizione per un confronto. Senza non è possibile discutere, ne parlare di "conoscenza" visto che non c'è.

"Ma porca la miseria, chi è qui il talebano?????"
Un talebano è colui che ad ogni critica mossa da persone che di SQL Server ne masticano un pò, rigetta ogni accusa sostenendo che la sua visione e quella giusta, sempre e comunque, utilizzando nomi che "fanno figo" come Cloud, Preventive Optimization, quando in realtà si sta parlando di una sola cosa: buon design e scelte pensate.
Nessun professionista serio (e vedo che tutti i commenti sono fatte da persone che reputo tali) sostiene che le soluzioni sono solamente bianche o nere, ma è ovvio che quando di discute - a meno di non specificare il contrario - si discute della soluzione che nella maggior parte dei casi sono applicabili. Ovvio che poi ci sono casi che devono essere valutati di volta in volta.

Ho già scritto molto, quindi mi fermo qui. Per tutto il resto concordo al 1000000% con Marco e Silvano, e non ho quindi nulla da aggiungere a quanto detto, soprattutto per quanto riguarda il discorso della RESPONSABILITA.

Non c'è da essere a favore o contro l'uso di GUID ne di qualsiasi altra funzionalità. C'è da essere in favore di un UTILIZZO CONSAPEVOLE e da esser contro ogni DISINFORMAZIONE chiunque possa fare.
24/12/2008 0.48 | Davide Mauri
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Davide, ho letto il tuo post, ma mi sembra che tu non abbia usato i GUID sequenziali (introdotti in SQL 2008) ma quelli completamente pseudocasuali.

id uniqueidentifier not null primary key default(newid())

Usando newsequentialid non dovrebbero essere ridotti i page split e la frammentazione degli indici?
24/12/2008 5.27 | Andrea
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Davide. Più che aver messo in bold, italic e underline le parole "parallel query plan" cosa devo fare?

@@Identity vs @@Scope_identity. Non hai letto i commenti. Mi rieferivo a Raffaeu quando diceva "ogni quanto avviene la pressione del tasto save allo stesso istante".

Talebano. Rileggi bene tutti i commenti e soprattutto il post.
Dici "Un talebano è colui che ad ogni critica mossa da persone che di SQL Server ne masticano un pò, rigetta ogni accusa sostenendo che la sua visione e quella giusta, sempre e comunque".
Bene in questo riconosco i commenti di Silvano e il tuo. Io ho espresso una *mia* preferenza al guid se non in casi da valutare. Conosci la parola valutare?
Inoltre tra i commenti solo Marco ha portato argomentazioni tecniche, per il resto ci sono dei link interessanti e il resto sono solo accuse rabbiose.

Il tuo commento è cieco. Posti senza neppure leggere con attenzione le parole che sono scritte. Mi sembrate un tantino agitati. C'è modo e modo di esprimersi in modo civile e non vi fa bene alla salute. Buon natale.

@Andrea. Una precisazione. I sequential guid sono stati introdotti nella 2005. Il grosso hiht di performance era nella 2000 come ben mostrano diversi benchmark che puoi trovare sulla rete.
24/12/2008 9.20 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Andrea
del SEQUENTIALGUID ne ho parlato in conclusione all'articolo: "se state usando SQL Server 2005 o superiori, un buon compromesso può essere l'uso di SEQUENTIALGUID, in modo che il problema della frammentazione dei dati sia quantomeno evitato, in quanto vengono generati valori GUID sequenziali, monotonici crescenti, e quindi al riparo dal problema della frammentazione. Rimane il fatto che un GUID rende gli indici "cicciotti" e quindi poco efficienti in termini di caching e I/O, ma se non ci può fare altrimenti, questo rappresenta un buon compromesso. Il migliore attualmente, IMHO."

@Raf
Ognuno leggerà e trarra le sue conclusioni. Sento cmq rumore di unghie sugli specchi.....

Mi chiedi se conosco la parola valutare. Forse non hai letto il mio blog. La conclusione che tiro è questa: "[I GUID] Sono quindi di evitare, in favore di un uso assolutistico di INT IDENTITY come Primary Key? NO, NO, e poi NO. Questo post non vuole mettere paura, ma mira a promuovere un utilizzo consapevole. Se per esigenze funzionali è necessario usare un GUID facciamolo, sapendo che però ha un costo."

Accuse "rabbiose" ?!?!? :-) ROTFL! Ho solo chiesto di usare un metodo scientifico quando si parla di questioni tecniche...converrai con me che senza prove tangibili si sta parlando di aria fritta......se è rabbioso questo....suvvia! :-)
E ovvio che sostengo con forza le mie convinzioni (visto che sono supportate dalla realtà) ma di rabbia non ce n'è proprio traccia...c'è fastidio per la lettura di affermazioni false e tendenziose, quello senza dubbio.

Buon Natale anche a te :-)
24/12/2008 9.58 | Davide Mauri
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Davide. Nel mio commento non ti ho fatto dire nulla. Cerca di fare altrettanto.
Questo post non è una discussione Guid vs int. Su UGI e in tanti altri posti queste discussioni sono già state fatte ampiamente e chiunque può farsi una opinione.
E poi non capisco il termine 'paura'. Ho scritto che leggere il bug feedback è istruttivo e ho sottolineato in bold, underline e italic che avviene solo in un caso molto particolare.
Il terrorismo lo state facendo voi.

Aria fritta. Esatto. Io ho postato e l'unico argomento tecnico è quello di Marco. Il resto è proprio aria fritta.
La rabbia c'è ed e chiaro secondo il gergo internet. Il tutto maiuscolo significa urlare e qui la voce l'avete alzata in due. Per non parlare del modo...
24/12/2008 13.05 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

"Io ho postato e l'unico argomento tecnico è quello di Marco"
Se sostieni che il mio post non è tecnico, francamente è inutile stare a discutere, visto che si nega l'evidenza. Neghi pure quello che hai scritto nero su bianco, visto che il tuo post cita testualmente "vivi più tranquillo e usa un bel Guid se non in casi tutti da valutare", mentre ora dici che il bug "avviene solo in un caso molto particolare".

Bah, inutile continuare a discutere con chi non vuol capire.

Il giorno che farai un post tecnico, con delle dimostrazioni a carico delle tue affermazioni si potrà tornare a discutere, fino a quel momento si perde solo tempo.
24/12/2008 13.15 | Davide Mauri
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Davide. Ma quando nel post è scritto ed evidenziato: "whenever a parallel query plan is generated" cosa devo dire di più????

Per quato riguarda il contenuto tecnico:
- il commento su @@Identity. Non era attinente. Io commentavo Raffaeu.
- discorso sull'hardware. Hai frainteso totalmente. Io ho detto che hoi visto più volte clienti che preferiscono investire in hardware piuttosto che in giornate spese in ottimizzazione. È una *constatazione* di quello che ho visto che in alcuni casi mi ha pure stupito. Rileggi bene.
- int identity. Discorso già fatto da Marco che condivido nel dettaglio tecnico, meno dal punto di vista architetturale.

Ma questo, come scrivevo a Marco, dipende da come uno imposta l'architettura di una applicazione. Da quando esiste ADO 2.0 io realizzo qusi esclusivamente applicazioni disconnesse. Usavo adUseClient in VC++ nel 1998 (presentato al TechEd di Nizza) spostando i recordset via dcom. Non ho alcuna intenzione (e non lo era questo post) di dare motivazioni pro o contro l'una o l'altra scelta.

Non ho neppure la pretesa di convincere che il mio punto di vista sia il migliore. Ma lo stesso dovrebbe valere per il vostro punto di vista.
Invece di un confronto come quello con Marco, da voi sento solo urla e, non in questo post, anche pesante maleducazione.

Per concludere il post è semplicemente un invito a leggere il feedback su connect e credere che chi legge si metta ad usare i guid sempre e comunque solo per questo post mi sembra offensivo nei confronti di chi legge.
24/12/2008 14.21 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Ciao a tutti,

Spesso passo per UGI a leggere sul muro qualche news e qualche post per vedere come si evolve la piattaforma .NET (ero developer .NET qualche anno fa, ora sviluppo su piattaforma Apple).

E' un peccato leggere questi commenti alle volte offensivi e provocatori contro una persona che ha solamente postato le sue idee. Credo che sul proprio blog si possa scrivere quello che piu si ritiene giusto (eticamente permettendo).

Per cui ringrazio Raffaele per avere postato le sue idee ed i suoi punti di vista. Torneranno utili a molte persone secondo me!. :)


Buon Natale a tutti!

Andrea
24/12/2008 15.58 | Andrea Gelati
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Caro Raffaele, caro Andrea,
io veramente inizio a non capire più se ci fate o se ci siete...
Visto che da queste parti (non parlo solo di questo blog, purtroppo) ormai l'aria che tira è un pò questa, vorrei solo riportare le cose su un piano concreto e precisare che:
- se parliamo di una cosa (secondo me abbastanza effimera) come la Netiquette, il primo a scrivere qualcosa in stampatello non sono stato io, basta andare indietro a rileggersi la cronologia dei post e chiunque può giudicare.
- visto che più volte è stato ribatito, di contenuti tecnici non mi sembra che il tuo post originale (e non solo questo...) e le tue successive risposte ne contenessero molti. Si parla di "punti di vista", di tanti "secondo me", e quant'altro. Mi sembra che nei commenti che sono stati fatti invece di contenuti tecnici ne siano stati espressi parecchi, e le risposte date sono sempre state evasive e fuori argomento
- di contenuti così offensivi e provocatori nei commenti non mi sembra di vederne, ma chiunque dotato di un minimo di intelligenza e senso critico può interpretare questo post e altri come quello su SQL CE e farsi una idea su da che parte sta la provocazione, a meno di non voler proprio essere palesemente in malafede.
25/12/2008 1.21 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

- di talebanesimi e altre facezie non ho iniziato io a parlarne, ma se vogliamo affrontare il problema seriamente anche qui possiamo analizzare quanto è stato scritto e arrivare ciascuno ai propri risultati.
- che il tema originale del mio commento non era sulla questione tecnica, che per altro mi trova in disaccordo con l'autore del post (ma questo non c'entra), quanto sulla "sentenza finale" del post stesso e sulla *responsabilità* che una figura "pubblica e conosciuta" di una community, che si fregia di un bollino blu con su scritto MVP, con il quale si presenta a clienti che lo stanno ad ascoltare anche per quello, dovrebbe sentire prima di scrivere certe cose in modo così assolutistico (perchè non l'ho scritta io quella frase...). Certamente che uno è libero di scrivere quello che ritiene giusto sul proprio spazio sul web, ma allo stesso modo un altro può commentare, no? O la cosa è monodirezionale?
- se proprio vogliamo stare attenti ai modi e alla forma, non ci sto a passare per il cattivo della situazione che se la fa con gli agnellini. Rileggiti un pò i vari commenti e le risposte, su queste pagine e fuori, e prima di fare l'agnellino sarebbe meglio tu ci pensassi 2 volte.
- che magari oggi con il mio lavoro oggi scriverò anche meno codice di quanto faccia tu, ma che non penso ti convenga andare a fare dei confronti sull'esperienza e competenza professionale, perchè potresti farti del male... dal training, alla consulenza agli speech pubblici...
- che nel suddetto lavoro purtroppo mi trovo molto spesso a contatto con clienti e partner in situazione di crisi dove i problemi sono nati perchè qualche sedicente "consulente Microsoft, che è anche MVP..." ha dato indicazioni non corrette su come organizzare e sviluppare una certa applicazione, e indovina alla fine con chi se la prendono questi signori?? Forse con il consulente stesso? Usa la fantasia...

Detto questo, che spero spieghi perchè sono stato così interessato a questo e ad altri thread, l'ultimo commento mi da veramente il polso della situazione di quanto poco abbia senso spendere tempo in questo genere di discussioni da queste parti, molto meglio utilizzarlo in qualcosa di più produttivo.

Buon Natale!

P.S: a proposito, l'ultimo commento sull'uso dei cursori lato client e di DCOM nel contesto della discussione sui GUID è veramente incomprensibile. Vorresti forse dire che esiste un legame tra lo scrivere codice di accesso ai dati in modalità disconnessa e l'uso di GUID come chiave e che questo è un requisito fondamentale? Voglio sperare di no, in caso contrario potrei provare a chiedere a David Sceppa se ha ancora in casa i suoi vecchi libri su ADO e insieme al mio su ADO.NET potrei mandarteli per spiegarti come si usano le chiavi logiche in un contesto disconnesso e distribuito con i Recordset o DataSet.
25/12/2008 1.22 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

È certamente meglio lasciare che ciascuno giudichi leggendo perché le cose sono palesi nei vari commenti, come ad esempio lo scrivere tutto maiuscolo.

Quanto all'esperienza e alla responsabilità non ho proprio nulla da temere perché sono stati i feedback dei clienti a dirmelo.
Fin dal primo commento a Marco ho chiarito, se ce ne fosse bisogno, che non c'era alcuna 'parola defintiva' sull'uso di int o guid. Tu invece ti sei scatenato in una raffica di post a senso unico. La scelta definitiva dipende sempre dal contesto del progetto e personalmente prediligo i guid ma non ho mai detto di usare solo questi. Fin'ora i risultati mi hanno dato ragione.

Quanto ai confronti, le gare non mi toccano proprio. Io non metto in dubbio la tua professionalità, ma ti interessa tanto la mia senza neppure sapere cosa faccio.

Per quanto riguarda il discorso MVP, il premio è per quanto si è detto e fatto in *passato*, dopo valutazione delle persone dei team interessati. Il fatto di fregiarsi di un prestigioso titolo come questo, è come un curriculum. Di sedicente quindi non c'è nulla e non sono io a dirlo.

Infine per l'ultimo commento non è certamente indispensabile l'uso del Guid ma è certamente preferibile. La valutazione dipende dal progetto ma è la *mia* scelta numero 1. E i fattori decisionali non sono solo la quantità e forma dei dati.
Non sei sicuramente daccordo ma per dirlo c'è modo e modo.
25/12/2008 14.44 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Io vorrei fare il punto della situazione per un secondo. Stiamo discutendo se usare o no GUID come chiave primaria e perché.
La definizione di chiave primaria é:
La chiave primaria è un insieme di attributi che permette di individuare univocamente una tupla in una relazione.
Bene, siamo daccordo entrambi che sia un INT che un GUID mi danno univocità. Ma a mio parere, entrambi non possono essere presi come oro colato. Pensiamo ad una semplicissima tabella ordini. Perché non posso usare il mio bel campo CODICE_ORDINE come chiave primaria? Perché devo obbligatoriamente seguire la moda del GUID se poi di per sé come design il GUID o l'INT non mi rappresentano nulla? Devo star li a crearmi una chiave primaria e poi dei vincoli check e constraint per far si che il codice ordine, magari legato ad una altra colonna mi garantiscano comunque una univocità?
Parliamo di prestazioni: indicizzazione.
Un indice cluster mi fornisce una struttura B-tree per otimizzare la ricerca delle informazioni, giusto? Nel mio gestionale andro' a cercare le informazioni per GIUD o INT o per codice ordine?
Quel che voglio dire é semplicemente che caso per caso, presi singolarmente in fase di design, bisogna decidere che tipologia di chiave primaria bisogna usare nella struttura dati. Non esistono MUST ma solamente BEST PRACTICE a mio parere.
26/12/2008 4.27 | raffaeu
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Raffaeu. Lo scopo del post non era affatto di disquisire sui pro e contro dei guid vs int ma di suggerire la lettura di quel feedback che la ritengo molto istruttiva a prescindere dal bug di per se.
La discussione sui pro e contro è già stata fatta sul forum di UGI in passato con un thread più che esaustivo in cui un po' tutti hanno dato il proprio contributo e con toni pacati.
Altre risorse/articoli ci sono in giro compresi i guid sequenziali e altre ottimizzazioni nell'uso dei guid presenti a partire da SQL 2005.

Detto questo, io non userei un codice_ordine per esempio perché non puoi sapere a priori come evolverà l'applicazione. Una cosa che mi è capitata di frequente è di vedere chiavi primarie stile "ALFKI" (degli esempi di sql server tanto per intenderci) che, per motivi di evoluzione dell'applicazione, col tempo non erano più univoche.
Avere chavi primarie svincolate dalla logica dei dati IMHO è un requisito fondamentale per poter evolvere bene l'applicazione.

L'int ha il vantaggio di essre un ottimo candidato per le key di un dictionary e genericamente in hashtable. Questo lo rendono estremamente performante nella ricerca (ho postato su differenze di dictionary e collection tempo fa qui nel mio blog).
Inoltre l'int ha il vantaggio di essere della dimensione di un registro della CPU e quindi l'algoritmo esegue molto meno I/O in memoria.
Fortunatamente le cache L2 (circa 1 ordine di grandezza più veloce della RAM) sono molto grosse e un algoritmo ben scritto può soffrire poco se qualcosa non riesce a stare nei registri che sono ovviamente pochi.

Il Guid ha il vantaggio di essere globalmente sempre univoco. In pratica negli scenari disconnessi hai sempre la certezza di non collidere mai con quanto è già presente sul DB. Ci sono dozzine di problematiche di cui tenere conto nella gestione di inserimento di un dato nel DB e l'uso del guid risolve in modo semplice buona parte di questi problemi.
Essendo un numero a 128 bit il guid non sta dentro un registro e quindi richiede maggiore I/O, oltre a fenomeni di aumentata frammentazione e page split come già detto negli altri commenti.
In certi scenari dove è possibile prevedere una estendibilità, l'uso di un Guid può essere una buona assicurazione. Mi è capitato di scrivere una estensione a TFS ma purtroppo c'erano degli int sul database che ci hanno obbligato a realizzare una logica molto più complessa. Ripeto: dipende dallo scenario.

Ovviamente questo breve riassunto non basta a decidere. Dipende dal tipo di applicazione e dal tipo di architettura utilizzata nell'applicazione. Per alcuni problemi relativi alle performance si può migliorare con una cache sull'application server, ma i fattori decisionali sono diversi.
26/12/2008 14.10 | Raffaele Rialdi
Gravatar

# Alto che film di natale!

Alto che film di natale!
27/12/2008 10.05 | Alessandro Scardova @ UgiDotNet
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Intervengo per dire un paio di cose, putroppo brevemente, ma si tratta di pur sempre di un commento.

La prima, voglio tranquillzare Silvano che nessuno prende nulla come oro colato, specialmente se lo trova letto su un blog... qualche anticorpo ormai ce lo siamo fatti tutti, solo uno stolto può prendere una riga scritta in un qualsiasi post e usarla come proprio credo. Persino le parole della Bibba debbono essere interpretate, figuriamoci quelle trovate sul web. Talebano è quello che rinuncia a ragionare sulle cose scritte, non quello che le scrive.

La seconda, tecnica, si riassume in una frase del post precdente "Avere chavi primarie svincolate dalla logica dei dati IMHO è un requisito fondamentale per poter evolvere bene l'applicazione." Che io interpreto, scusadomi con Raf se non colgo l'interpretazione originale, nel domain model non dovrebbero esserci riferimenti vincolanti alle primary key. Cioè le primary key non dovrebbero essere usate nel model per gestire la logica relazionale. Qalsiasi sia il meccanismo usato nel model esso dovrebbe essere "mappato" sulle effettive chiavi di relazioni solo all'ultimo momento, durante la persistenza del dato nel db.

Mi fermo qua, ringraziando Raf e gli altri per l'interessante post.
27/12/2008 10.41 | Alessandro Scardova
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

"Il Guid ha il vantaggio di essere globalmente sempre univoco. In pratica negli scenari disconnessi hai sempre la certezza di non collidere mai con quanto è già presente sul DB. Ci sono dozzine di problematiche di cui tenere conto nella gestione di inserimento di un dato nel DB e l'uso del guid risolve in modo semplice buona parte di questi problemi."
Benchè ciò sia vero - anche se sarebbe bello fare esempi di queste tematiche e non stare sul vago, altrimenti si potrebbero creare più dubbi nel lettore che quanti se ne mirino a risolvere - il post nasce parlando di GUID sulle PK.....ed il problema è tutto qui. Un GUID se serve può traquillamente essere usato come Alternate Key, in modo da non appesantire tutte le FK che si riferiscono alle PK e limitare al massimo il problema di frammentazione dei dati e di ingigantimento degli indici.
Teniamo ben presente questa cosa, perchè il punto della discordia è tutto li...non certo sull'utilità o meno di usare GUID in altri casi. Quella è una questione architetturale che dipende strettamente dalle necessità funzionali e non è quindi possibile dibatterla solamente da un punto di vista tecnico (se non parlando più in generale, come ho fatto nel mio post)

PS
GUID si scrive maiuscolo, non sto urlando :-) ROTFL (pure questo non è urlo, neh!...è che si scrive cosi!) :-) :-) :-)
27/12/2008 10.56 | Davide Mauri
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Sul contenuto non mi pronuncio. Sono parte della schiera dei lettori UGIDotNet che si cibano dei post dei "grandi" per ampliare le proprie conoscenze, e non ho la competenza necessaria per poter intervenire in un dibattito così importante. Però sulla forma si. E mi sembra doveroso spezzare una lancia a favore di Raf, per il semplice motivo che questo è il suo blog. E continuo a sostenere (come ho fatto in altri casi, a proposito di qualcuno che se n'è andato dal muro UGIDotNET a causa di flame vari) che ogniuno nel suo blog deve poter dire quello che gli pare, anche se fosse una madornale stupidagine, anche se a scrivere è un mostro sacro come Raf. Inoltre ergersi a difesa degli sprovveduti lettori è un po' offensivoe leggermente saccente. Leggendo i vari commenti saltando il contenuto e osservando la sola forma, mi domando perchè persone che conosco e stimo tantissimo (come Davide) si lascino prendere dal sacro fuoco della "verità scientifica" e vi immolino i semplici principi della tolleranza. Caro Davide, il tuo post è bellissimo, il tuo comento al post di Raf molto meno, lasciatelo dire.
Quindi per terminare: GUID o non GUID, a tutti voi Buon Natale e auguri di tanta tolleranza per il 2009!
27/12/2008 11.48 | Nicolò Carandini
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Quoto Alessandro, talebano è chi legge e non interpreta, non chi scrive.
E ritenere che ci sia in giro gente che confonde il blog di Raf con weloveraf è presumere che ci siano in giro un po’ (troppi) stupidi.
Uno legge il muro di ugi, poi legge il muro di ugiss (o viceversa): si fa un’idea, si dice “interessante!”, ringrazia chi ha scritto e ci pensa su. Poi sta a lui valutare la soluzione da adottare in base al suo caso reale; in quel momento è anche sperabile che non si sia limitato a due post su due blog, e comunque la responsabilità della scelta sarà soltanto sua.
Mi permetto di aggiungere che “dimostrazione scientifica” e “parola definitiva” sono, nella scienza moderna, espressioni che fanno a cazzotti: così si passa senza neppure accorgersene dalla parte di Bellarmino e fra 400 anni tocca chiedere scusa ;)

auguri a tutti!
27/12/2008 12.29 | Vladimiro
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Nicolo
La disinformazione va sempre evidenziata e se possibile corretta. Non si vuole essere ne saccenti ne criticoni, si vuole semplicemente essere oggettivi. Questo perchè la conoscenza è la cosa più importante che l'uomo ha, ed è quindi necessario preservarla, altrimenti poi ci si lamenta che i DB sono vecchi e che non scalano, quindi si fanno degli errori oggettivi che inficiano tali giudizi e fanno trarre conclusioni affrettate. Il che conduce ha prendere decisioni sbagliate ed esageratamente costose, contribuendo a rendere il panorama IT italiano come lo vediamo: decadente.

A me interessa semplicemente dare alle persone la possibilità di scegliere in modo corretto, non mi ergo a difesa dei lettori, quanto della corretta informazione....il che non mi sembra una brutta cosa, visto che l'informatica è cosi complessa e mutevole che nessuno può sapere tutto di tutto, ed è quindi necessario affidarsi ad informazioni di terze parti per prendere delle decisioni anche fondamentali. Il detto "fate agli altri quello che vorreste fatto a voi" è quantomai calzante: a me piacerebbe poter avere un posto dove leggere delle informazioni corrette e fidate, potendo quindi evitare di riscoprire l'acqua calda ogni volta, in modo da poter elevare la qualità del mio lavoro. Per farlo però è necessario che la fiducia che viene data sia controbilanciata da una pari dose di responsablità da parte di chi è investito di tale importante ruolo.

In questo ambito, IMHO, il fatto che una persona in vista scriva un post ampiamente mal interpretabile e ancor più negativo. E poi...."mostri sacri"? Per favore, qui l'unico mostro sacro dovrebbe essere il metodo scientifico e mi pare che ce ne sia stato ben poco....

Non capisco poi questa difesa del diritto di dire quello che si vuole nel proprio blog: nessuno lo ha messo in discussione, ma cosi - spero - nessuno metta in discussione il diritto di commentare, tanto più quando lo si fa con evidenze scientifiche e pratiche.

Non confondiamo la tolleranza con il diritto di critica e non confondiamo una discussione seppure animata come qualcosa che non è....siamo professionisti e siamo adulti e tutti sappiamo che abbiamo delle differenze di vedute: dovremmo forse astenerci dal professarle solo perchè altrimenti qualcuno si offende?

Mi piacerebbe sapere poi dove il miei commenti si possono ritenere offensivi per qualcuno.....perchè francamente non vedo nulla di offensivo, a parte il fatto che ho opinioni diverse in merito alla questione tecnica. Ah forse ho capito! Ho chiarito con un post tecnico cosa relamente succede e qual'è l'impatto di una scelta piuttosto che di un'altra! Delitto: come chiedere la moviola a bordocampo....
27/12/2008 12.41 | Davide Mauri
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

"Il che conduce ha prendere "
Arght! :-) Mi flagello da solo :-).....managgia alla voglia di scrivere in fretta! :-)
27/12/2008 12.50 | Davide Mauri
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Non entro nella questione tecnica, credo si sia già detto detto tutto. Nonostante la mia diretta esperienza con i GUID in un applicativo enterprise, non voglio aggiungere altra carne al fuoco. Anche perché, ripeto, si è già detto tutto e la mia (dis)avventura con i GUID è già contenuta nel bellissimo articolo di Davide. Entro invece nel merito della forma dei contenuti, soprattutto dei commenti di Silvano che IMHO è stato molto maleducato nell'esposizione. Silvano cerca di avere più rispetto per le persone che non la pensano come te. Altrimenti passi solo da cafone e non da esperto.
27/12/2008 15.08 | Mallox
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Caro Mallox,
hai ragione a volte la mia foga mi porta ad essere un pò troppo accorato nello acrivere, anche se proprio alla maleducazione non mi sembrava di essere arrivato, ma se lo dici tu ci credo. Ho anche scritto però che non mi va di fare la parte del lupo con i poveri agnellini, e che prima di accusarmi di essere brutto e cattivo magari sarebbe meglio rileggersi bene tutta la storia. A proposito di cafonaggine però, la prossima volta potresti anche mettere un nome o un link dal quale si possa capire chi sei invece di nasconderti dietro ad un nick, visto che tutti gli altri attori di questa storia hanno partecipato con la loro facci alla discussione, non credi?

Cari Alessandro, Nicolò e Vladimiro, purtroppo non mi invento le cose e alle prossime occasioni cercherò di farmi dare il permesso dai diretti interessati per pubblicare quanti e chi sono le persone che ci hanno riportato frasi simili a quelle che ho citato nei vari post. Non tutto il mondo degli sviluppatori italiani segue direttamente eventi ed attività di gruppi come Ugi, ma moltissimi ne leggono blog e articoli, e il mio intervento iniziale riguardava un concetto come la responsabilità nello scrivere quelle frasi che già ho evidenziato. Forse voi frequentate un ambiente privilegiato da questo punto di vista, ma avendo visitato qualcosa come 200 clienti e partner nell'ultimo anno e mezzo vi assicuro che le cose stanno proprio in quel modo. Io, forse con troppa foga, chiedevo solo questo, senza limitare nessuna libertà di scrivere quello che si vuole nel proprio blog, ma solo di applicare un pò di buon senso, che mi sembra merce molto in crisi in questo momento....

Caro Raf,
io sono certamente molto poco tecnico ma non ho molto capito le frasi legate ai registri della CPU. Il problema che si evidenziava con Davide non riguarda tanto il costo delle operazioni necessarie alla CPU per caricare le informazioni dalla RAM ai registri/cache, quanto alle operazioni di I/O su disco e all'utilizzo inefficiente dei buffer di memoria di SQL Server, problema che è di diversi ordini di grandezza superiore al precedente.
Nel caso qualcuno che legge questi commenti volesse rinfrescarsi alcuni concetti di base, a questo link (cid-048d495cc0b87794.skydrive.live.com/.../....zip) può trovare un whitepaper abbastanza dettagliato su come funzionavano le cose con SQL 2000 che, per gli aspetti principale, non è cambiato un gran chè anche nelle due versioni successive.

Pace fratelli!!! :)
27/12/2008 16.05 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Alessandro,
pur essendo completamente ignorante e piuttosto refrattario al termine "domain model" :) riconosco il concetto da te espresso perchè si mappa praticamente 100% con quello di "surrogate key" (al contrario delle "natural key") che vive da almeno 30 e passa anni nel mondo dei database server.
Non è nemmeno nuova la tecnica, classica nel mondo della programmazione "disconnessa" del layer di accesso ai dati, di utilizzare delle chiavi temporanee (tipicamente interi, autoincrementali e negativi) per la gestione delle relazioni in strutture dati (tipo master-detail) non ancora persistite nel database (ad esempio con i "damn' evil" DataSet :) che poi venivano sostituite dai valori generati server-side solo dopo aver eseguito l'inserimento nelle tabelle.
Questo tipo di approccio è sempre stato usato in tutti quei casi dove non era necessario conoscere a priori il valore della chiave logica effettiva dell'entità (es. id ordine), ma era comunuque importante conoscere quel valore per svolgere attività successive come l'inserimento di altre entità ad esso legate in altre tabelle. In questo scenario l'uso di un GUID non avrebbe di per se molto senso.
Siamo tutti d'accordo che "ALFKI" non sia la miglior candidata come primary key, ma se invece di dare una occhiata al vecchio Northwind si guarda anche solo AdventureWorks (che non è perfetto ma dove si trovano già diversi esempi interessanti anche tenendo conto il DW costruito di conseguenza) secondo me si può notare come l'approccio basato su chiavi naturali e surrogate può coprire la maggioranza degli scenari.
Poi ci sono anche tutti gli altri casi in cui è necessario conoscere a priori il valore della chiave di un record (oppure ne si è anche solo convinti...) oppure altri casi quali il mitco "numero fattura", ma qui entriamo in un altro campo.
27/12/2008 16.58 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Raffaeu,
partiamo dalla tua frase:

"Perché non posso usare il mio bel campo CODICE_ORDINE come chiave primaria? Perché devo obbligatoriamente seguire la moda del GUID se poi di per sé come design il GUID o l'INT non mi rappresentano nulla? Devo star li a crearmi una chiave primaria e poi dei vincoli check e constraint per far si che il codice ordine, magari legato ad una altra colonna mi garantiscano comunque una univocità?
Parliamo di prestazioni: indicizzazione.
Un indice cluster mi fornisce una struttura B-tree per otimizzare la ricerca delle informazioni, giusto? Nel mio gestionale andro' a cercare le informazioni per GIUD o INT o per codice ordine?"

Se il tuo campo "CODICE_ORDINE" è la chiave naturale della tabella Ordini di per se non ci sarebbero problemi bloccanti a farne la chiave primaria. Il fatto di utilizzare una chiave surrogata da vantaggi in termini di "immutabilità" dell'entità al variare del valore della chiave, di flessibilità nel cambiamento dei requisiti (l'attributo o gli attributi che identificano una entità potrebbero cambiare nel tempo) ma soprattutto di prestazioni. Pensa tipicamente a quei bei "codici parlanti" che popolavano i db di qualche decennio fa, magari campi carattere di lunghezza abbondante, e a cosa succede proprio parlando di indicizzazione quando quel codice ordine è utilizzato in altre decine di tabelle con tanto di indici a supporto delle varie operazioni di Join di cui normalmente le applicazioni sono piene. Il risultato in termini di performance nell'avere una chiave primaria e relative FK più leggere possibile è direttamente proporzionale a quante relazioni sono presenti in quel database. Questo ovviamente non preclude in nessun modo l'avere un indice non clustered sulla tua colonna Codice Ordine a supporto delle ricerche dirette su quel campo.
Ricorda che l'indice cluster per la ricerca di un valore univoco come la chiave primaria è tipicamente meno efficiente di un indice non clustered, perchè la densità delle chiavi all'interno di una pagina da 8K sarà maggiore e quindi minore la quantità di letture necessarie per trovare un singolo record. L'indice Clustered al contrario è più adatto per ricerca di "range" di valori visto che determina l'ordine fisico dei record nelle pagine del db.
Certo l'approccio basato su chiavi surrogate non è perfetto, essendo valori "non naturalmente riconosciuti" come parte del modello logico o del dominio (oddio, l'ho detto... :) del problema può essere a volte scomodo ma, nella maggioranza degli scenari, i vantaggi sono tipicamente superiori agli svantaggi.
27/12/2008 17.41 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Silvano: una certa esperienzucola ce l'ho anche io e anche io ho avuto il piacere di avere come maestro Antonio Sponza. So benssimo a cosa ti riferisci nei tuoi commenti e non trovi certo in me in fan sfegatato del Guid, anche se non mi piace che vengano demonizzate tout-court soluzioni che ne fanno uso, tutto qua: se come te ho trovato gente che vede il guid come manna dal cielo ho anche trovato gente che lo vede come il fumo negli occhi.
Hai indovinato, in effetti tendo ad usare il Guid solo dove serve e come surrogate key, come la definisci tu, ma non voglio farne una regola: in fondo il Guid è solo un datatype a 128 bit. Per chiuderla con una battuta, quello che ammazza non è la pistola, ma la mano che preme il grilletto.
27/12/2008 17.51 | Alessandro Scardova
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Yup, concordo! :)
Mi sembra di aver già scritto da qualche parte che dopo essermi andato a vedere un pò di codice su come funzionano le repliche apprezzo molto l'uso dei GUID in scenari di quel genere. Così come in applicazioni online-offline o che consolidano dati da sorgenti diverse sono altri scenari interessanti. Anche se tipicamente i GUID vengono usati come colonna di "servizio" per gestire la riconciliazione dei dati distribuiti più che come chiave vera e propria.
Cmq, sul grilletto non si può non essere d'accordo :););)
27/12/2008 18.52 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Grazie a tutti gli intervenuti. E per chi ama le allusioni io alle 15:08 ero sugli sci, con testimoni e senza PC.

@Alessandro
"Avere chiavi primarie svincolate ...". Si nel senso che se ho una PK non guid, che in qualche modo è coinvolta nella logica della gestioine dei dati, c'è il rischio che questa non sia più univoca in futuro, a causa di qualche evoluzione nell'applicazione. Il guid è ovviamente un'eccezione perché essendo sempre univoco non può incorrere in questo specifico problema.
Ho visto usare primary key su due colonne di dati "di logica" pur di usare quei dati. Inutile elencare i problemi che ne sono derivati.

@Davide. Frammentazione. I Guid danno quel genere di problema che, come ogni problema, deve essere *valutato* insieme ai vantaggi che ne derivano. Decidere a priori di escluderli è altrettanto dannoso. I Page split sai bene che possono anche accadere con PK di tipo int. Non puoi liquidare il problema ai solo fatto dei guid.
E quando ho parlato di premature optimization a Marco mi riferivo al fatto che "scendere" da un Guid ad un int è semplice, mentre il contrario non lo è altrettanto (e non parlo ovviamente solo del lavoro sul DB).
Surrogate key. Certo, e chi ha mai detto che non è una possibile strada? Io ho solo detto che prediligo l'uso del guid come PK e non ho mai detto di usare solo quella.

@Silvano.
I/O. Sebbene una dimensione maggiore di una key implichi certamente un numero maggiore di I/O su disco, questo genere di operazioni è alleviabile con un buon hardware. In ufficio un collega ha messo su dei test con fiber channel con sustained read/write da paura (200MB in read e 190MB in write).
Quello che tu chiami "uso inefficiente della memoria" si riferisce probabilmente al discorso che facevo io. Il singolo guid non sta in un registro e gli algoritmi per l'indexing delle keys usano più memoria e c'è maggiore accesso alla RAM.
Gli Xeon nascono anche per risolvere questo tipo di problemi sulla memoria e oggi abbiamo CPU con 12M di L2 (se non ricordo male la L2 sugli Xeon va a full-speed rispetto alle CPU client). Per calarci nel pratico, su 20M di righe il guid prende circa 1MB e un index sui guid prende circa 700K.
Questo significa che i performance hit di 10 anni fa, sia per disco che per CPU, sono *molto* diversi rispetto a quelli che ci sono oggi, grazie all'hardware.
Ripeto per l'ennesima volta. La scelta dipende dall'applicazione. I vantaggi nell'uso del guid vanno valutati mettendo sul piatto della bilancia tanti tanti altri parametri che non vivono solo nel DB e la questione non si può liquidare in 'best practice' come un'etichietta da apporre su un prodotto in saldi.


Un'ultima considerazione sul discorso generale delle performance. Io sostengo che il costo degli strumenti che forniscono le migliori performance devono essere considerati molto attentamente.
Se cercassi sempre il top delle performance, scriverei applicazioni in assembler (e l'esempio è calzante perché c'è un francese nel newsgroup di MASM che scrive anche le UI in assembler) o tuttalpiù in C++/Win32.
Il motivo per cui accettiamo dei compromessi a scapito delle performance è perché riusciamo:
1. a soddisfare il requisito del cliente (che è l'unica cosa che conta veramente)
2. a mantenere perlomeno decente il ciclo di vita del nostro software. Cioè una volta concluso lo sviluppo è necessario che quel codice sia dannatamente manutenibile e di conseguenza anche il meno complesso possibile.
Quindi la discussione accademica sulle performance in assoluto è IMHO totalmente sterile.
27/12/2008 22.35 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

No, ovviamente non intendevo quello per "uso inefficiente della memoria", quanto piuttosto il fatto che una chiave di 16 byte in una struttura relazionale dove magari viene referenziata come FK in 3 o 4 tabelle collegate, con relativi indici, visto che dovrò pure fare qualche join per recuperare le varie informazioni, significa utilizzare una maggiore quantità di pagine caricate in memoria, una minore densità di righe per pagina e tipicamente un aumento delle attività di I/O sul disco che, per quanto veloce e performante, avrà sempre dei limiti. Non solo

"Per calarci nel pratico, su 20M di righe il guid prende circa 1MB e un index sui guid prende circa 700K"

Ecco, onestamente non ho capito come hai fatto questi conti, puoi spiegarlo per favore?
28/12/2008 1.00 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Aggiungerei anche che un servizio come SQL Server è in generale una risorsa condivisa, sulla quale possono insistere più applicazioni che lavorano su più database e che non è affatto sterile parlare di ottimizzazione delle performance in questi contesti anzi, si tratta della realtà di tutti i giorni! Se rifacendo i conti del tuo commento precedente ti accorgessi che invece di 1Mb stessimo parlando di qualcosa intorno ai 320 :), e stessimo parlando di un database mediamente complesso con circa un paio di centinaia di tabelle che utilizzano questo approccio per chiavi primarie e foreign key collegate, beh.... forse qualche problemino ce lo potremmo iniziare ad avere sia a livello di buffer di memoria che di attività di I/O su disco che, vorrei ricordare, in una applicazione OLTP non è legata al troughput dei canali SCSI o in fibra ma dai tempi di accesso che non sono poi cambiati così tanto negli ultimi 10 anni... forse parlassimo di applicazioni tipo DW allora potremmo parlarne, ma il ragionamento di fondo non cambia più di tanto.
Se poi preferiamo non pensare alle performance ma accorgerci dei problemi di performance quando l'applicazione è già andata in produzione beh... è una scelta anche questa, perchè metterla in discussione? W la manutenibilità :)
28/12/2008 2.10 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

"I Page split sai bene che possono anche accadere con PK di tipo int. Non puoi liquidare il problema ai solo fatto dei guid "
Si lo so bene, infatti ne nei commenti nè nel post ho mai parlato di page split, controlla bene :-)
La frammentazione non è solamente dovuta ai page split. Essi sicuramente ne contribuiscono alla formazione ma non sono il problema maggiore nel caso dell'utilizzo di un GUID non sequenziale, in quanto i dati sono già dispersi per il fatto che il GUID è un valore randomico, ed il page split influsce in modo minore a disperdere ulteriormente i dati.


28/12/2008 14.58 | Davide Mauri
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Silvano. Si, mi spiace ho sbagliato a riportare i calcoli, erano 20K e non 20M le righe. Sono dei conti che ho fatto parecchio tempo fa comparando le size del db con colonna di tipo int o guid. Ricordo che il conto non era semplice perché ovviamente anche la riga ha un costo e SQL giustamente alloca a pagine. Alla fine la comparazione con lo stesso numero di righe ma datatype differenti mi è sembrata più affidabile e ho trovato ordini di grandezza simili su articoli/blog in giro su internet.
Anche se i numeri sono molto differenti, per portare in L2 tutti quei dati il numero di accessi alla RAM è decisamente modesto (circa 26 accessi per caricare i 320M in 12M di L2). Il discorso che facevo nell'altro commento era che l'hardware di oggi ti permette di abbattere tempi che 10 anni fa avevano un impatto decisamente più alto.

Performance. Il mio intento non è quello di fare a gara di performance tra int e guid. Siamo sempre stati daccordo sul fatto che sia più performante in assoluto un int. Ma è proprio il discorso di performance assolute che è IMHO sterile.
Le performance sono ovviamente importanti ma cos'è la performance se non quella che soddisfa i requisiti del cliente?
Le performance, in quanto requisito, devono essere valutate prima di andare in produzione e ho anche già scritto che, dal punto di vista applicativo, è meno doloroso cambiare PK da un guid ad un int a sviluppo in corso piuttosto che il contrario.
28/12/2008 15.23 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Davide. Non stavo collegando frammentazione a page split. Volevo solo che fosse chiaro a chi legge che page split ci sono comunque e vanno valutati a prescindere da guid o int.
Con i sequential guid (che è sempre stato possibile usarli, anche con SQL2000) la randomicità non c'è. Una parte del guid è il MAC address e quindi è costante, il resto è un valore in funzione del tempo e perciò progressivo.
28/12/2008 15.28 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Mah, saranno anche conti difficili da fare ma se faccio Start->Run->Calc e subito dopo moltiplico 20M * 16 byte ottengo 305.18Mb, e anche senza considerare l'overhead dei metadati a livello di singola riga in una tabella, la frammentazione dei record nella pagina e altre cose di poco conto, con meno di quei 305Mb di certo non ci stò... non c'è bisogno di andare a cercare articoli su Internet per fare un calcolo come questo.
Se poi non sono sicuro e voglio controllare quanto spazio SQL Server ha allocato per quei dati posso sempre usare:

select * from sys.dm_db_partition_stats where object_id = OBJECT_ID('NomeTabella')

e da qui alla colonna in_row_data_page_count avere una indicazione di quante pagine da 8K sono state usate per contenere le righe e gli indici di una determinata tabella.
Detto questo, continuo a non capire questo riferimento costante alla cache L2 del processore, temo che con il nostro discorso non c'entri proprio nulla. Infatti SQL Server per poter fare qualsiasi tipo di operazione sui dati ha bisogno di caricare le suddette pagine dal disco (se già non sono state caricate in precedenza) all'interno dei propri buffer dati, che non risiedono nella cache del processore ma in RAM. Solo dopo, quando verranno fatte operazioni sui dati, quelle informazioni passeranno nella cache.

A tal proposito, nel caso tu volessi vedere la quantità di pagine caricate nei buffer di memoria, magari filtrando per oggetto o per database, puoi utilizzare alcune DMV con una query come questa:

select b.database_id, db=db_name(b.database_id)
,p.object_id
,object_name(p.object_id) as objname
,p.index_id
,buffer_count=count(*)
from sys.allocation_units a,
sys.dm_os_buffer_descriptors b,
sys.partitions p
where a.allocation_unit_id = b.allocation_unit_id
and a.container_id = p.hobt_id and b.database_id = DB_ID('NomeDB') and p.object_id = OBJECT_ID('NomeTabella')
group by b.database_id,p.object_id, p.index_id
order by buffer_count desc

Se parliamo di performance, in una applicazione OLTP che genera I/O tipicamente random (e non sequenziali come l'OLAP/Reporting) una tra le caratteristiche hw dei dischi più importante sono i tempi di accesso, che negli ultimi 10 anni non sono cambiati significativamente perchè legati direttamente alla velocità di rotazione dei piattelli dei dischi stessi. Essendo già in produzione 10 anni fa dei dischi con ottime performance (15K rpm) l'hardware non aiuta a mettere delle pezze alle applicazioni scritte male. Una riprova sono i numeri dei benchmark TPC/C che sono aumentati in modo assolutamente non lineare con il progredire delle componenti hw ma che hanno raggiunto valori superiori solo creando sistemi "monstre".

Come ho già scritto diverse volte, il problema qui non sono le performance assolute che sono evidentemente poco significative, il problema è che questo genere di scelte ha impatti importanti anche in casi molto concreti, con clienti normali, con numeri non stratosferici di dati e di utenti concorrenti, e che mai come in un database server risparmiare "il grammo" è importante, perchè le risorse non sono infinite e soprattutto sono condivise.
28/12/2008 15.57 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

"Con i sequential guid (che è sempre stato possibile usarli, anche con SQL2000)": si ma solo se te li generi a mano; la funzione NEWSEQUENTIALID è stata introdotta in SQL 2005.
28/12/2008 16.20 | Davide Mauri
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Silvano. L'errore su quella cifra è palese. Il perché dei conti è semplice: non posso assumere che lo storage del guid sia as-is. Per cui una controprova era necessaria perché non ci fosse ulteriore overhead non dipendente dallo storage puro del solo guid.

Il discorso I/O dipende dagli scenari perché per determinare il set di dati da restituire nel resultset, le key possono essere mantenute in memoria e non credo che vengano rilette tutte le pagine del db da disco ogni volta.
Se restituisci grossi set di dati o esegui conti sulle righe, etc. etc. dovranno essere rilette le pagine filtrate da disco, quindi I/O discretamente grandi. Ma questo tipo di operazioni non sono comuni a tutte le applicazioni.
Se restituisci pochi dati alla volta, cosa comune nelle applicazioni con accesso di tipo disconnesso, le pagine lette da disco dovrebbero essere decisamente poche.
L'impatto dell'accesso alla RAM c'è sempre per costruire il set filtrato.

Io non metto in dubbio che in moti scenari l'impatto dell'I/O sia molto significativo ma dipende dal tipo di applicazione e dalla sua architettura. A volte puoi, a volte no e quindi, in quei casi, ti tocca limare il grammo.
28/12/2008 16.27 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Davide. Si certo. In origine la funzione uuidcreate creava solo guid sequenziali. Poi per motivi di privacy è stata 'randomizzata' e la versione originale esposta per compatibilità nella uuidcreatesequential.
Ricordo Don Box che, per ovviare ai problemi di privacy prima di questa nuova api, aveva esposto un servizio di creazione di guid sul suo website.
Quindi la creazione sequenziale è in realtà quella "vera" ed è sempre stata usabile anche se in sql 2000 doveva essere fatto a mano (ma con poche righe di extended sp).
28/12/2008 16.34 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

"Il perché dei conti è semplice: non posso assumere che lo storage del guid sia as-is. Per cui una controprova era necessaria perché non ci fosse ulteriore overhead non dipendente dallo storage puro del solo guid."

"Il discorso I/O dipende dagli scenari perché per determinare il set di dati da restituire nel resultset, le key possono essere mantenute in memoria e non credo che vengano rilette tutte le pagine del db da disco ogni volta."

Illuminante!! Fosse stato cosi' lampante dall'inizio che non era chiaro di cosa si stava parlando la discussione sarebbe stata piu' profiqua per chi ha letto o leggera' in futuro. Comunque qualcosa porteranno a casa anche cosi'.

Approfitto per fare gli auguri di buon anno a tutti e a presto.
Passo e chiudo.
28/12/2008 17.13 | Silvano Coriani [MSFT]
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

@Silvano. Non so a cosa alludi, ma io mi sono solo limitato a rispondere alle questioni che sono state sollevate.
Ripeto che il post non aveva la velleità di dare alcuna sentenza su guid o int. Poi ben vengano le discussioni pacifiche in cui ciascuno dice la sua.
Con questo non pretendo di convincere nessuno ma spero solo che siano spunti per riflettere, tutto qui. E forse questo è l'unico punto su cui siamo daccordo.
Auguri di buon anno a te e a tutti quanti.
28/12/2008 19.06 | Raffaele Rialdi
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Scusate se torno ora sul thread... ho visto che l'argomento di usare chiavi naturali invece che surrogate è emerso qua e là ma non è stato affrontato a viso aperto, mentre è di quello che si dovrebbe parlare in termini di scelte architetturali.
Cito come riferimento questo messaggio di Joe Celko (di cui vi consiglio di leggere i libri, a patto di leggerli in maniera critica e senza prendere tutto come oro colato) risalente al 2004: www.tech-archive.net/.../2178.html
Personalmente, adoro questa frase:

>> I know many people use Identity columns to generate unique id. <<
>And that is a major reason so many database project produce bad data,
>fail out right and why I could easily bill between $1000-2000 per day
>when I did clean up work or SQL training. Better than half of my clean
>up jobs used IDENTITY, GUIDs or other autonumbering schemes that could
>not be verified.

Chi è senza peccato scagli la prima pietra. Io sicuramente non posso farlo!
Buon 2009 e buone primary key a tutti! :)

Marco
31/12/2008 11.04 | Marco Russo
Gravatar

# Windows 7 Download Failure, SQL Server, GUID e Primary Key

Come ormai tutti sanno, visto che nella rete sembra non si parli d’altro, il giorno del download di Windows
08/05/2009 12.18 | Impedance Mismatch
Gravatar

# re: Un motivo in più per usare i Guid come chiavi primarie

Interessante questo articolo, grazie per le informazioni e buone feste a tutti
29/12/2009 12.27 | tonup

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 5 and 7 and type the answer here:

Powered by: