Domanda

In passato ho lavorato su numerosi sistemi di database in cui lo spostamento delle voci tra i database sarebbe stato molto più semplice se tutte le chiavi del database fossero state GUID/UUID valori.Ho preso in considerazione l'idea di intraprendere questa strada alcune volte, ma c'è sempre un po' di incertezza, soprattutto riguardo alle prestazioni e agli URL non leggibili al telefono.

Qualcuno ha lavorato a lungo con i GUID in un database?Quali vantaggi otterrei seguendo questa strada e quali sono le probabili insidie?

È stato utile?

Soluzione

Vantaggi:

  • Può generarli offline.
  • Rende la replica banale (al contrario di int, il che la rende DAVVERO difficile)
  • Di solito gli ORM sono come loro
  • Unico in tutte le applicazioni.Quindi possiamo utilizzare i PK dal nostro CMS (guida) nella nostra app (anche guida) e sapere che non avremo MAI uno scontro.

Svantaggi:

  • Maggiore utilizzo dello spazio, ma lo spazio è economico (più)
  • Impossibile ordinare per ID per ottenere l'ordine di inserimento.
  • Può sembrare brutto in un URL, ma davvero, che cavolo stai mettendo una VERA chiave 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 "addestrato" su un sistema che è stato replicato ovunque, quindi DOVEVAMO averli.YMMV.

Penso che la questione dei dati duplicati sia spazzatura: puoi ottenere dati duplicati comunque lo fai.Le chiavi surrogate di solito sono disapprovate ovunque io abbia lavorato.Utilizziamo però il sistema simile a WordPress:

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

AGGIORNAMENTO:Quindi questo riceve molti +1 e ho pensato che dovrei sottolineare un grande svantaggio dei GUID PK:Indici cluster.

Se hai molti record e un indice cluster su un GUID, le prestazioni di inserimento faranno SCHIFO, poiché ottieni inserti in posizioni casuali nell'elenco di elementi (questo è il punto), non alla fine (che è veloce)

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

Altri suggerimenti

@Matt Sheppard:

Supponiamo che tu abbia un tavolo di clienti.Sicuramente non vuoi che un cliente esista nella tabella più di una volta, altrimenti si creerà molta confusione nei reparti vendite e logistica (soprattutto se le righe multiple sul cliente contengono informazioni diverse).

Quindi hai un identificatore cliente che identifica univocamente il cliente e ti assicuri che l'identificatore sia conosciuto dal cliente (nelle fatture), in modo che il cliente e gli addetti al servizio clienti abbiano un riferimento comune nel caso abbiano bisogno di comunicare.Per garantire che non vi siano record cliente duplicati, aggiungi un vincolo di unicità alla tabella, tramite una chiave primaria sull'identificatore del cliente o tramite un vincolo NOT NULL + UNIQUE sulla colonna dell'identificativo del cliente.

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

Qualche "architetto" potrebbe dirti che "oh, ma ci occupiamo noi del... vero vincolo di unicità del cliente nel nostro livello di app!".Giusto.La moda per quanto riguarda i linguaggi di programmazione per scopi generali e (soprattutto) i framework di livello intermedio cambia continuamente e generalmente non sopravviverà mai al tuo database.E c'è una buona probabilità che ad un certo punto avrai bisogno di accedere al database senza passare attraverso la presente applicazione.== Problemi.(Ma fortunatamente tu e l '"architetto" ve ne siete andati da tempo, quindi non sarete lì per ripulire il caos.) In altre parole:Mantieni vincoli evidenti nel database (e anche in altri livelli, se hai tempo).

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

Il vantaggio principale è che puoi creare ID univoci senza connetterti al database.E gli ID sono univoci a livello globale, quindi puoi combinare facilmente dati da diversi database.Sembrano piccoli vantaggi ma in passato mi hanno risparmiato molto lavoro.

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.

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

Modificare ho unito le mie due risposte a questa domanda

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

I GUID potrebbero causare molti problemi in futuro se vengono utilizzati come "uniqifiers", consentendo ai dati duplicati di entrare nelle tabelle.Se desideri utilizzare i GUID, considera di mantenere comunque i vincoli UNIQUE su altre colonne.

Perché nessuno menziona le prestazioni?Quando hai più join, tutti basati su questi fastidiosi GUID, le prestazioni andranno a rotoli, ci sono stato :(

Un altro piccolo problema da considerare con l'utilizzo dei GUIDS come chiavi primarie se si utilizza quella colonna anche come indice cluster (una pratica relativamente comune).Subirai un colpo durante l'inserimento a causa della natura di una guida che non inizia in alcun modo in sequenza, quindi ci saranno suddivisioni di pagina, ecc. quando inserisci.Solo qualcosa da considerare se il sistema avrà un IO elevato...

chiavi-primarie-id-rispetto-guide

Il costo dei GUID come chiavi primarie (SQLServer2000)

Miti, GUID vs.Incremento automatico (MySQL5)

Questo è davvero quello che vuoi.

Professionisti dell'UID

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

GUID Contro

  • È ben 4 volte più grande del tradizionale valore dell'indice a 4 byte;questo può avere gravi implicazioni in termini di prestazioni e archiviazione se non stai attento
  • Difficile da eseguire il debug (dove userid='{BAE7DF4-DDF-3RG-5TY3E3RF456AS10}')
  • I GUID generati dovrebbero essere parzialmente sequenziali per ottenere prestazioni ottimali (ad esempio, newsequentialid() su SQL 2005) e per consentire l'uso di indici cluster

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

Gli RDBM solitamente assicurano l'unicità delle chiavi primarie e assicurano le ricerche 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 pari a 2).Ora, un ID intero sequenziale farebbe sì che gli inserimenti si verifichino semplicemente uno lato dell'albero, lasciando intatta la maggior parte dei nodi fogliari.L'aggiunta di UUID casuali farà sì che gli inserimenti dividano i nodi foglia in tutto l'indice.

Allo stesso modo, se i dati archiviati sono per lo più temporanei, spesso accade che sia necessario accedere ai dati più recenti e unirli a quelli più numerosi.Con gli UUID casuali i pattern non ne trarranno beneficio e colpiranno più righe di indice, necessitando quindi di più pagine di indice in memoria.Con gli ID sequenziali, se i dati più recenti sono più necessari, le pagine hot-index richiederebbero meno RAM.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top