Quali sono gli svantaggi dell'utilizzo di UUID o GUID come chiave primaria?


61

Vorrei costruire un sistema distribuito. Devo archiviare i dati nei database e sarebbe utile utilizzare un UUID o un GUID come chiave primaria su alcune tabelle. Presumo che sia un inconveniente con questo design poiché UUID / GUID è piuttosto grande e sono quasi casuali. L'alternativa è utilizzare un INT incrementato automaticamente o LUNGO.

Quali sono gli svantaggi dell'utilizzo di UUID o GUID come chiave primaria per le mie tabelle?

Probabilmente userò Derby / JavaDB (sui client) e PostgreSQL (sul server) come DBMS.


Perché sarebbe utile? Su quali inconvenienti ti concentri maggiormente? La risposta a ogni domanda DB questa vaga è "dipende". Puoi darci maggiori dettagli? Sei più interessato a leggere o scrivere performance? di quale livello di distribuzione stiamo parlando?
Brian Ballsun-Stanton,

@Brian: gli UUID nei sistemi distribuiti sono utili poiché è possibile creare la chiave primaria sui client e quindi caricare i dati in modo asincrono sul server. Penso principalmente agli svantaggi delle prestazioni di lettura. Usare molti JOIN su UUID non è forse così buono? Ad esempio, un client aggiunge un articolo (UUID, nome, fornitore, creatore) a un sistema di inventario, quindi il database locale viene sincronizzato con il database centrale sul server.
Jonas,

1
Penso che senza alcuni commenti più chiari su questo sarà al massimo "dipende". Senza quelli, vado per VtC.
jcolebrand

C'è un articolo che parla degli effetti GUID e non GUID sugli indici cluster in SQL Server che potresti trovare interessanti anche se è correlato a un diverso prodotto SQL: x.co/Twpp
Jeff

Ho notato che il documento Derby non elenca l'UUID come tipo di dati. Potresti prendere in considerazione un'alternativa come H2 Database Engine (un puro database Java come Derby) che elenca un tipo di dati UUID . Naturalmente Postgres offre un eccellente supporto per archiviare , indicizzare e generare in modo efficiente i valori UUID.
Basil Bourque,

Risposte:


29

Dipende dalla funzione di generazione e dalle dimensioni dei tavoli finali

I GUID devono essere identificatori univoci a livello globale . Come discusso nella documentazione di Postgres 8.3 non ci sono metodologie universalmente appropriate per generare questi identificatori, ma postgreSQL viene fornito con alcuni candidati più utili.

Dal campo di applicazione del problema e dalla necessità di scritture offline , hai praticamente eliminato l'uso di qualsiasi cosa tranne un GUID, e quindi non ci sono vantaggi compensativi di altri schemi.

Da un punto di vista funzionale, la lunghezza della chiave di solito non è un problema per nessun tipo di sistema moderno, a seconda del numero di letture e delle dimensioni della tabella. Come metodologia alternativa, i client offline possono raggruppare nuovi record senza una chiave primaria e semplicemente inserirli al momento della riconnessione. Poiché postgreSQL offre il tipo di dati "Seriale", i client non dovranno mai determinare l'ID se possono eseguire una semplice scrittura nel database.


3
Dannazione dormi, sei andato e hai lasciato che Brian rispondesse alla domanda. Sì, il requisito di "aggiornamenti offline" ha completamente cambiato l'intero concetto lì.
jcolebrand

Muahahahaah! :: twirls mustache evilly ::
Brian Ballsun-Stanton

1
Anche con le scritture offline sarebbe possibile usare gli INT. Ad esempio, usando due colonne in {Node_ID, Item_ID}cui ogni nodo ha una Node_IDe una Item_IDche viene auto-incrementata per nodo.
Jonas,

@Jonas ~ Sì, è fattibile. Tuttavia, uno dei motivi per cui la maggior parte delle persone contempla persino i GUID è la replica di contenuto separata globalmente in altri database. Voglio dire che il termine stesso è piuttosto QED lì.
jcolebrand

Per quanto riguarda le architetture master / slave o i client con connessione sparsa + architetture del server principale, potrebbe essere possibile utilizzare un global_id (SERIAL) sul master e un global_id (BIGINT) + local_id (SERIAL) sugli slave. Gli schiavi svolgono il loro lavoro locale usando local_id e si impegnano quando possono verso il master, il master riceve i dati e gli concede un global_id che restituisce allo slave, lo slave aggiorna il campo global_id (per riferimento come riferimento nel parlare con il server o con altri slave).
Mihai Stancu,

22

Un altro consiglio: non utilizzare mai i GUID come parte dell'indice cluster. I GUID non sono sequenziali, quindi se fanno parte dell'indice cluster, ogni volta che si inserisce un nuovo record, il database dovrebbe riorganizzare tutte le sue pagine di memoria per trovare il posto giusto per l'inserimento, nel caso con int (bigint) auto-increment, esso sarebbe solo l'ultima pagina.

Ora, se guardiamo ad alcune realizzazioni di db: 1.) MySQL - le chiavi primarie sono raggruppate, senza possibilità di cambiare comportamento - la raccomandazione è di non usare affatto i GUID qui 2.) Postgres, MS-SQL - puoi fare GUID come chiave primaria non cluster e utilizzare un altro campo come indice cluster, ad esempio autoincrement int.


Ciò che proponi per Postgres può essere fatto anche in MySQL, con una struttura leggermente diversa: auto_increment PK (chiave cluster), GUID con indice univoco (non cluster).
ypercubeᵀᴹ

Questo non è sempre vero. A seconda del throughput del sistema disco, la sincronizzazione dell'accesso all'ultima pagina potrebbe essere il collo di bottiglia. blog.kejser.org/2011/10/05/…
mwilson

2
"A differenza di Microsoft SQL Server, il clustering su un indice in PostgreSQL non mantiene tale ordine. È necessario riapplicare il processo CLUSTER per mantenere l'ordine." In che modo CLUSTER ON migliora le prestazioni dell'indice
bartolo-otrit

Una versione più condensata delle informazioni @ bartolo-otrit legata a: stackoverflow.com/a/4796685/1394393 . Questa risposta non mi sembra davvero rilevante, poiché questa domanda riguarda PG e sembra assumere somiglianze con SQL Server e MySQL che non esistono.
jpmc26,

database would need to rearrange all its memory pages to find the right place for insertion=> Non penso che sia il caso di Postgres, poiché il clustering è facoltativo e le nuove righe vengono memorizzate non ordinate.
Flavien,

3

Dipende.

Scherzi a parte, con tutto ciò che hai dato finora, questo è il più lontano possibile.

Perché sarebbe utile usare gli UUID? Perché non usi INT? Perché non puoi semplicemente indicizzare gli UUID più tardi? Capisci cosa significa avere un elenco ordinato con la chiave di un UUID e inserire un UUID casuale (non sequenziale) dopo qualche milione di righe?

Su quale piattaforma funzionerà? Quanti dischi? Quanti utenti? Quanti record?


7
Come ho scritto nel mio commento, se utilizzo UUID i client possono aggiungere righe al database senza una connessione al server e successivamente sincronizzarsi con il server. Non posso farlo se uso INT per la chiave primaria, perché più client possono utilizzare la stessa chiave primaria per elementi diversi. Bene, è inutile ordinare l'elenco su una colonna UUID, sarebbe più utile ordinarlo su una colonna timestamp. No, non so cosa significhi inserire un UUID casuale non sequenziale dopo qualche milione di righe, ecco perché faccio questa domanda.
Jonas,

L'applicazione sarà scritta in Java e i miei client usano Windows, Mac o Linux. I client useranno i comuni computer desktop che di solito hanno un disco. Il numero di utenti e record dipende da quanti clienti ottengo, ma sarà di circa 5000 per cliente e cliente.
Jonas,

1
Il commento offline ha cambiato tutto. Vedi quali ulteriori dettagli fa?
jcolebrand
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.