Vantaggi e svantaggi delle chiavi del database GUID / UUID

Ho lavorato su un numero di sistemi di database in passato in cui le voci in movimento tra i database sarebbero state rese molto più semplici se tutte le chiavi del database fossero state valori GUID / UUID . Ho preso in considerazione l’idea di seguire questa strada alcune volte, ma c’è sempre un po ‘di incertezza, in particolare per quanto riguarda le prestazioni e gli URL non leggibili oltre il telefono.

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

vantaggi:

  • Può generarli offline.
  • Rende banale la replica (al contrario di quella di INT, il che rende VERAMENTE difficile)
  • Di solito gli ORM piacciono a loro
  • Unico tra le applicazioni. Quindi possiamo usare i PK del nostro CMS (guid) nella nostra app (anche guid) e sapere che non otterremo MAI uno scontro.

svantaggi:

  • Uso dello spazio più grande, ma lo spazio è economico (er)
  • Imansible ordinare per ID per ottenere l’ordine di inserimento.
  • Può sembrare brutto in un URL, ma in realtà, WTF stai facendo mettere una chiave REAL DB in un URL !?
  • Più 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 dappertutto, quindi dovevamo averli. YMMV.

Penso che la questione dei dati duplicati sia spazzatura: puoi ottenere dati duplicati, comunque lo fai. Le chiavi surrogate sono solitamente disapprovate ovunque io abbia mai lavorato. Tuttavia, utilizziamo il sistema simile a WordPress:

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

AGGIORNAMENTO: Quindi questo ha fatto +1 molto, e ho pensato che dovrei indicare un grosso svantaggio di GUID PK: Clustered Indexes.

Se disponi di molti record e di un indice cluster su un GUID, le tue performance di inserimento saranno SUCK, dato che otterrai inserimenti in posizioni casuali nell’elenco di elementi (questo è il punto), non alla fine (che è veloce)

Quindi, se hai bisogno di inserire le performance, magari usare un INT auto-inc e generare un GUID se vuoi condividerlo con qualcun altro (cioè mostrarlo a un utente in un URL)

@ Matt Sheppard:

Supponi di avere un tavolo di clienti. Sicuramente non vuoi che un cliente esista sul tavolo più di una volta, o che ci sia molta confusione nei reparti vendite e logistica (specialmente se le righe multiple del cliente contengono informazioni diverse).

Quindi hai un identificatore del cliente che identifica in modo univoco il cliente e ti assicuri che l’identificatore sia conosciuto dal cliente (nelle fatture), in modo che il cliente e il personale del servizio clienti abbiano un riferimento comune nel caso in cui debbano comunicare. Per garantire l’assenza di record dei clienti duplicati, si aggiunge 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 ragione (che non riesco a pensare), ti viene chiesto di aggiungere una colonna GUID alla tabella del cliente e di renderla la chiave primaria. Se la colonna dell’identificatore del cliente è ora lasciata senza una garanzia di unicità, stai chiedendo guai futuri in tutta l’organizzazione perché i GUID saranno sempre unici.

Alcuni “architetti” potrebbero dirti che “oh, ma gestiamo il vero vincolo di unicità del cliente nel nostro livello di app!”. Destra. La moda per quanto riguarda i linguaggi di programmazione generici e (soprattutto) i quadri di livello medio cambia continuamente e generalmente non uscirà mai dal database. E ci sono ottime possibilità che a un certo punto sarà necessario accedere al database senza passare attraverso la presente applicazione. == Problemi. (Ma per fortuna tu e l'”architetto” siete lontani, quindi non sarete lì a ripulire il casino.) In altre parole: mantenete evidenti vincoli nel database (e in altri livelli, se avete il tempo).

In altre parole: ci possono essere buoni motivi per aggiungere colonne GUID alle tabelle, ma per favore non cadere nella tentazione di rendere le tue ambizioni più basse per coerenza all’interno delle informazioni reali (== non-GUID).

I principali vantaggi sono la possibilità di creare ID univoci senza connettersi al database. E gli ID sono unici al mondo, quindi puoi combinare facilmente i dati di diversi database. Questi sembrano piccoli vantaggi ma mi hanno risparmiato un sacco di lavoro in passato.

I principali svantaggi sono un po ‘più di memoria necessaria (non un problema sui sistemi moderni) e gli ID non sono leggibili in modo veramente umano. Questo può essere un problema durante il debug.

Ci sono alcuni problemi di prestazioni come la frammentazione dell’indice. Ma quelli sono facilmente risolvibili (pettini di jimmy nillson: http://www.informit.com/articles/article.aspx?p=25862 )

Modifica unì le mie due risposte a questa domanda

@ Matt Sheppard Penso che voglia dire che è ansible duplicare le righe con GUID diversi come chiavi primarie. Questo è un problema con qualsiasi tipo di chiave surrogata, non solo GUID. E come ha detto, è stato risolto con facilità aggiungendo significativi vincoli univoci alle colonne non chiave. L’alternativa è usare una chiave naturale e quelli hanno problemi reali ..

GUID potrebbero causare molti problemi in futuro se vengono utilizzati come “uniqifiers”, consentendo l’inserimento di dati duplicati nelle tabelle. Se si desidera utilizzare GUID, si prega di considerare di mantenere ancora vincoli UNIQUE su altre colonne.

Perché nessuno menziona le prestazioni? Quando si hanno più join, tutti basati su questi cattivi GUID, le prestazioni passeranno attraverso il pavimento, sono state lì 🙁

Un altro piccolo problema da considerare con l’utilizzo di GUID come chiavi primarie se si utilizza anche tale colonna come indice cluster (una pratica relativamente comune). Stai andando a colpire inserto a causa della natura di un guid non iniziare sequenziale in ogni caso, quindi la loro sarà divisioni di pagina, ecc, quando si inserisce. Solo qualcosa da considerare se il sistema avrà un IO alto …

GUID-chiavi primarie-IDS-versus-

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

Miti, GUID e Autoincrement (MySQL 5)

Questo è davvero quello che vuoi.

UID Pro

  • Unico su ogni tavolo, ogni database, ogni server
  • Consente una facile fusione di record da diversi database
  • Consente una facile distribuzione dei database su più server
  • Puoi generare ID ovunque, invece di dover andare al database
  • La maggior parte degli scenari di replica richiede comunque colonne GUID

GUID Cons

  • È un enorme 4 volte più grande del tradizionale valore dell’indice a 4 byte; questo può avere serie implicazioni di prestazioni e memorizzazione se non si presta attenzione
  • Ingombrante da eseguire il debug (dove userid = ‘{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}’)
  • I GUID generati dovrebbero essere parzialmente sequenziali per le migliori prestazioni (ad esempio, newsequentialid () su SQL 2005) e per abilitare l’uso di indici cluster

C’è una cosa che non è realmente affrontata, vale a dire l’uso di ID casuali (UUIDv4) come chiavi primarie danneggerebbe le prestazioni dell’indice della chiave primaria . Succederà se la tua tabella è raggruppata attorno alla chiave.

Gli RDBM solitamente assicurano l’unicità delle chiavi primarie e assicurano la ricerca tramite una 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 causerebbe l’inserimento degli inserti solo su un lato dell’albero, lasciando intatti la maggior parte dei nodes foglia. L’aggiunta di UUID casuali farà sì che gli inserimenti suddividano i nodes foglia su tutto l’indice.

Allo stesso modo, se i dati memorizzati sono per lo più temporali, è spesso il caso che i dati più recenti debbano essere consultati e uniti maggiormente. Con UUID casuali i pattern non trarranno beneficio da questo, e colpiranno più file di indice, quindi necessitano di più delle pagine indice in memoria. Con ID sequenziali se i dati più recenti sono più necessari, le pagine di indice a caldo richiederebbero meno RAM.