Vantaggi e svantaggi delle chiavi del database GUID / UUID


222

In passato ho lavorato su numerosi sistemi di database in cui lo spostamento di voci tra database sarebbe stato reso molto più semplice se tutte le chiavi del database fossero state valori GUID / UUID . Ho pensato di seguire questa strada alcune volte, ma c'è sempre un po 'di incertezza, soprattutto per quanto riguarda le prestazioni e gli URL non leggibili al telefono.

Qualcuno ha lavorato a lungo con i GUID in un database? Quali vantaggi otterrei andando in quel modo e quali sono le probabili insidie?


1
Jeff ha pubblicato un post " Chiavi primarie: ID contro GUID ".
jfs,

1
può anche utilizzare Hi-Lo per client remoti: stackoverflow.com/questions/282099/whats-the-hi-lo-algorithm
Neil McGuigan


Posizione aggiornata per il post di Jeff Atwood su " Chiavi primarie: ID contro GUID ". Grazie a @jfs per il riferimento.
Adam Katz,

@jfs Il link è stato modificato in blog.codinghorror.com/primary-keys-ids-versus-guids
cr0ss

Risposte:


229

vantaggi:

  • Possono generarli offline.
  • Rende la replica banale (al contrario di int, il che la rende DAVVERO dura)
  • Gli ORM di solito sono come loro
  • Unico tra le applicazioni. Quindi possiamo usare i PK dal nostro CMS (guid) nella nostra app (anche guid) e sapere che non avremo MAI uno scontro.

svantaggi:

  • Uso dello spazio maggiore, ma lo spazio è economico (er)
  • Impossibile ordinare per ID per ottenere l'ordine di inserimento.
  • Può sembrare brutto in un URL, ma davvero, WTF stai facendo inserire una chiave REAL DB in un URL !? (Questo punto è contestato nei commenti seguenti)
  • Difficile eseguire il debug manuale, ma non così difficile.

Personalmente, li uso per la maggior parte dei PK in qualsiasi sistema di dimensioni decenti, ma mi sono "allenato" su un sistema che è stato replicato ovunque, quindi DOVREBBE averli. YMMV.

Penso che la cosa dei dati duplicati sia spazzatura: puoi ottenere dati duplicati comunque. Le chiavi surrogate di solito sono disapprovate su dove io abbia mai lavorato. Usiamo il sistema simile a WordPress però:

  • ID univoco per la riga (GUID / qualunque cosa). Mai visibile all'utente.
  • l'ID pubblico viene generato UNA VOLTA da un campo (ad es. il titolo - rendilo il titolo dell'articolo)

AGGIORNAMENTO: Quindi questo ottiene + 1 molto, e ho pensato di sottolineare un grande svantaggio di GUID PK: Clustered Indexes.

Se disponi di molti record e di un indice cluster su un GUID, la tua performance di inserimento SUCCHERÀ, poiché ottieni inserimenti in posizioni casuali nell'elenco di elementi (questo è il punto), non alla fine (che è veloce)

Quindi, se hai bisogno di inserire le prestazioni, potresti usare un INT auto-inc e generare un GUID se vuoi condividerlo con qualcun altro (es. Mostralo a un utente in un URL)


184
[WTF, stai inserendo una chiave REAL DB in un URL !?] Non sei sicuro del motivo per cui ciò ti disturba. Cos'altro useresti? Guarda Stack Overflow ... Ha valori di IDENTITÀ nell'URL dappertutto e funziona perfettamente. L'uso delle chiavi DB negli URL non impedisce di applicare la sicurezza.
Euro Micelli,

20
No, non lo è, ma le cose come la SEO sono generalmente migliori se non c'è una chiave al suo interno, in particolare qualcosa come un GUID. Certo, può essere risolto facilmente, quindi immagino che sia stata una dichiarazione un po 'troppo ampia
Nic Wise,

7
Buona risposta, sarebbe bello se si aggiungessero anche informazioni sugli svantaggi delle prestazioni dell'utilizzo dei GUID; ad esempio l'unione, l'ordinamento e l'indicizzazione da essi saranno tutti più lenti rispetto all'utilizzo di numeri interi. Le guide sono fantastiche, ma hanno un costo che può essere una seccatura quando le prestazioni sono fondamentali.
Doctor Jones,

26
Tieni a mente una cosa, le persone cambiano spesso pagina, domanda, titoli del forum. Per SEO è utile avere qualcosa come un piccolo ID nell'URL in modo che se il titolo cambia, sai ancora dove inoltrare le persone provenienti da un URL VECCHIO. example.com/35/old-and-bustedè appena diventato example.com/35/new-hotnesse la tua app può semplicemente controllare il titolo e inoltrare l'utente con un 301.
Xeoncross

9
L'indicizzazione di un GUID è costosa e lenta, il che li rende candidati davvero poveri per le chiavi primarie.
Matthew James Davis,

14

@Matt Sheppard:

Supponi di avere una tabella di clienti. Sicuramente non vuoi che un cliente esista nella tabella più di una volta, o accadrà molta confusione nei tuoi dipartimenti di vendita e logistica (specialmente se le righe multiple sul cliente contengono informazioni diverse).

Quindi hai un identificatore del cliente che identifica in modo univoco il cliente e ti assicuri che l'identificatore sia noto al cliente (nelle fatture), in modo che il cliente e il servizio clienti abbiano un riferimento comune nel caso in cui debbano comunicare. Per garantire che i record dei clienti non siano duplicati, è necessario aggiungere un vincolo di unicità alla tabella, tramite una chiave primaria sull'identificatore del cliente o tramite un vincolo NOT NULL + UNIQUE nella colonna dell'identificatore del cliente.

Successivamente, per qualche motivo (a cui non riesco a pensare), ti viene chiesto di aggiungere una colonna GUID alla tabella dei clienti e renderla la chiave primaria. Se la colonna dell'identificatore del cliente è ora lasciata senza una garanzia di unicità, stai chiedendo problemi futuri in tutta l'organizzazione perché i GUID saranno sempre unici.

Alcuni "architetti" potrebbero dirti che "oh, ma gestiamo il vero vincolo di unicità dei clienti nel nostro livello di app!". Destra. La moda per quanto riguarda quei linguaggi di programmazione per scopi generici e (soprattutto) i quadri di livello intermedio cambia continuamente e generalmente non supererà mai il tuo database. E c'è una buona probabilità che a un certo punto dovrai accedere al database senza passare attraverso la presente applicazione. == Problemi. (Ma per fortuna tu e l '"architetto" siete spariti da tempo, quindi non sarete lì per ripulire il casino.) In altre parole: mantenete evidenti vincoli nel database (e anche in altri livelli, se avete il tempo).

In altre parole: potrebbero esserci buoni motivi per aggiungere colonne GUID alle tabelle, ma per favore non cadere nella tentazione di ridurre le tue ambizioni di coerenza all'interno delle informazioni reali (== non GUID).


1
Senti senti! Adoro la tua pagina di confronto SQL tra l'altro. Estremamente utile. L'unica cosa che mi manca è un log delle modifiche.
Henrik Gustafsson,

3
Penso che questa risposta abbia bisogno di alcuni chiarimenti: questo presuppone che gli UUID non vengano mai usati come chiavi primarie. Non so da dove provenga questo presupposto, ma devo ancora vedere un sistema che non ti consente di usarli come tali. So che è una vecchia risposta, suppongo che i vantaggi dell'utilizzo degli UUID nei sistemi distribuiti non fossero così ampiamente conosciuti all'epoca (?).
TNE

12

Perché nessuno menziona le prestazioni? Quando hai più join, tutti basati su questi cattivi GUID, le prestazioni passeranno attraverso il pavimento, state lì :(


1
Puoi approfondire questo come nella situazione in cui devo introdurre UUID (o simile), ma sono preoccupato di usarli come chiave primaria.
Joe Tidee,

1
Gli UUID sono solo 4 volte più grandi degli interi ... (se il tuo database ha un tipo UUID)
Jasen,

11

I GUID possono causare molti problemi in futuro se vengono utilizzati come "uniqifiers", consentendo ai dati duplicati di entrare nelle tabelle. Se si desidera utilizzare i GUID, considerare di mantenere ancora i vincoli UNIQUE su altre colonne.


11
Questo è il nocciolo del problema: l'introduzione di un GUID rende unica ogni riga. Ma le parti non artificiali delle file possono improvvisamente contenere duplicati (diverse versioni della verità).
Troels Arvin,

8
+1 per compensare. Capisco cosa intendi, ma è espresso male.
Stefano Borini,

11

I principali vantaggi sono che è possibile creare ID univoci senza collegarsi al database. E gli ID sono univoci a livello globale in modo da poter facilmente combinare i dati da diversi database. Questi sembrano piccoli vantaggi, ma mi hanno risparmiato molto lavoro in passato.

Gli svantaggi principali sono un po 'più di spazio di archiviazione necessario (non un problema sui sistemi moderni) e gli ID non sono realmente leggibili dall'uomo. Questo può essere un problema durante il debug.

Ci sono alcuni problemi di prestazioni come la frammentazione dell'indice. Ma quelli sono facilmente risolvibili (guide pettine di Jimmy Nillson: http://www.informit.com/articles/article.aspx?p=25862 )

Modifica ha unito le mie due risposte a questa domanda

@Matt Sheppard Penso che significhi che puoi duplicare le righe con diversi GUID come chiavi primarie. Questo è un problema con qualsiasi tipo di chiave surrogata, non solo con i GUID. E come ha detto, viene facilmente risolto aggiungendo vincoli univoci significativi a colonne non chiave. L'alternativa è usare una chiave naturale e quelli hanno problemi reali.


Conosco le guide del pettine e quelle che aiutano a risolvere il problema dell'indicizzazione (INSERT performance). "I principali svantaggi sono un po 'più di spazio di archiviazione necessario " Ciò influirà sulle prestazioni a causa delle grandi dimensioni del file di database?
Amit Joshi,

8

Un altro piccolo problema da considerare con l'utilizzo di GUIDS come chiavi primarie se si utilizza anche quella colonna come indice cluster (una pratica relativamente comune). Stai andando a fare un colpo su insert a causa della natura di un guid che non inizia comunque in sequenza, quindi le loro saranno divisioni di pagina, ecc. Quando si inserisce. Solo qualcosa da considerare se il sistema avrà un IO elevato ...


6

GUID-chiavi primarie-IDS-versus-

Il costo dei GUID come chiavi primarie (SQL Server 2000)

Miti, GUID vs Autoincrement (MySQL 5)

Questo è davvero quello che vuoi.

UID Pro

  • Unico su ogni tabella, ogni database, ogni server
  • Consente una facile fusione di record da diversi database
  • Consente una facile distribuzione di database su più server
  • È possibile generare ID ovunque, invece di dover andare di andata e ritorno nel database
  • La maggior parte degli scenari di replica richiede comunque colonne GUID

GUID Cons

  • È enorme 4 volte più grande del tradizionale valore dell'indice a 4 byte; questo può avere gravi conseguenze in termini di prestazioni e archiviazione se non stai attento
  • Ingombrante per il debug (dove userid = '{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • I GUID generati dovrebbero essere parzialmente sequenziali per le migliori prestazioni (ad es. Newsequentialid () su SQL 2005) e per consentire l'uso di indici cluster

1

C'è una cosa che non viene realmente affrontata, vale a dire l'uso di ID casuali (UUIDv4) come chiavi primarie danneggerà le prestazioni dell'indice della chiave primaria . Accadrà indipendentemente dal fatto che la tabella sia raggruppata o meno attorno alla chiave.

Gli RDBM di solito assicurano l'unicità delle chiavi primarie e assicurano le ricerche per chiave, in una struttura chiamata BTree, che è un albero di ricerca con un grande fattore di ramificazione (un albero di ricerca binario ha un fattore di ramificazione di 2). Ora, un ID intero sequenziale farebbe sì che gli inserimenti avvengano solo su un lato dell'albero, lasciando intatti la maggior parte dei nodi foglia. L'aggiunta di UUID casuali farà sì che gli inserimenti suddividano i nodi foglia in tutto l'indice.

Allo stesso modo se i dati memorizzati sono prevalentemente temporali, spesso accade che i dati più recenti debbano essere consultati e uniti maggiormente. Con UUID casuali i pattern non trarranno vantaggio da questo e colpiranno più righe di indice, richiedendo quindi più pagine di indice in memoria. Con gli ID sequenziali se i dati più recenti sono più necessari, le pagine dell'indice attivo richiederebbero meno RAM.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.