MongoDB
 sql >> Database >  >> NoSQL >> MongoDB

Utilizzo di UUID invece di ObjectID in MongoDB

L'uso degli UUID in Mongo è certamente possibile e ragionevolmente ben supportato. Ad esempio, i documenti Mongo elencano gli UUID come una delle opzioni comuni per _id campo.

Considerazioni

  • Prestazioni – Come menzionato in altre risposte, i benchmark mostrano che gli UUID causano un calo delle prestazioni per gli inserti. Nel peggiore dei casi misurati (passando da 10 milioni a 20 milioni di documenti in una raccolta) sono circa 2-3 volte più lenti:la differenza tra l'inserimento di 2.000 (UUID) e 7.500 (ObjectID) documenti al secondo. Questa è una grande differenza, ma il suo significato dipende interamente dal tuo caso d'uso. Inserirai in batch milioni di documenti alla volta? Per la maggior parte delle app che ho creato, il caso comune è l'inserimento di singoli documenti. Gli stessi benchmark mostrano che, per quel modello di utilizzo, la differenza è molta più piccolo (6.250 -vs- 7.500; ~20%). Non insignificante.. ma nemmeno sconvolgente.
  • Portabilità – Molte altre piattaforme DB hanno un buon supporto UUID, quindi la portabilità sarebbe migliorata. In alternativa, poiché gli UUID sono più grandi (più bit), è possibile ricomprimere un ObjectID nella "forma" di un UUID. Questo approccio non è bello come la portabilità diretta, ma ti dà un modo per "associare" gli ObjectID e gli UUID esistenti.
  • Decentramento – Uno dei grandi punti di forza degli UUID è che sono universalmente unici. Ciò rende pratico generarli ovunque, in modo decentralizzato (in contrasto, ad esempio, con un valore autoincrementante, che richiede una fonte di verità centralizzata per determinare il valore "successivo"). Naturalmente, anche gli ID oggetto Mongo offrono questo vantaggio. La differenza è che gli UUID si basano su uno standard di oltre 15 anni e sono supportati su (quasi?) tutte le piattaforme, le lingue, ecc. Questo li rende molto utili se hai bisogno di creare entità (o specificamente, set di correlati entità) in sistemi disgiunti, senza interagire con il database. Puoi creare un set di dati con ID e chiavi esterne, quindi scrivere l'intero grafico nel database in un momento futuro senza conflitti. Sebbene ciò sia possibile anche con Mongo ObjectID, trovare il codice per generarli/lavorare con il formato sarà spesso più difficile.

Correzioni

Contrariamente ad alcune delle altre risposte:

  • Gli UUID hanno il supporto nativo di Mongo – Puoi usare UUID() funzione nella Mongo Shell esattamente nello stesso modo in cui useresti ObjectID(); per convertire una stringa UUID in un oggetto BSON equivalente.
  • Gli UUID non sono particolarmente grandi – Quando codificato utilizzando il sottotipo binario 0x04 sono 128 bit, rispetto ai 96 bit degli ObjectID. (Se codificati come stringhe lo faranno essere piuttosto dispendioso, prendendo circa 288 bit.)
  • Gli UUID possono includere un timestamp – In particolare, UUIDv1 codifica un timestamp con 60 bit di precisione, rispetto ai 32 bit degli ObjectID. Si tratta di oltre 6 ordini di grandezza in più di precisione, quindi nanosecondi anziché secondi. In realtà può essere un modo decente per archiviare i timestamp di creazione con maggiore precisione rispetto al supporto degli oggetti Mongo/JS Date, tuttavia...
    • La build in UUID() la funzione genera solo UUID v4 (casuali), quindi, per sfruttare questo, dovresti fare affidamento sulla tua app o sul driver Mongo per la creazione di ID.
    • A differenza degli ObjectID, a causa del modo in cui gli UUID sono suddivisi in blocchi, il timestamp non fornisce un ordine naturale. Questo può essere buono o cattivo a seconda del tuo caso d'uso. (I nuovi standard potrebbero cambiarlo; vedere l'aggiornamento 2021 di seguito.)
    • Includere timestamp nei tuoi ID a volte è una cattiva idea. Finisci per perdere il tempo creato dei documenti ovunque sia esposto un ID. (Ovviamente gli ObjectID codificano anche un timestamp, quindi questo è in parte vero anche per loro.)
    • Se lo fai con UUID v1 (conforme alle specifiche), stai anche codificando parte dell'indirizzo MAC del server, che può potenzialmente essere utilizzato per identificare la macchina. Probabilmente non è un problema per la maggior parte dei sistemi, ma non è nemmeno l'ideale. (I nuovi standard potrebbero cambiarlo; vedere l'aggiornamento 2021 di seguito.)

Conclusione

Se pensi al tuo Mongo DB in isolamento, gli ObjectID sono la scelta più ovvia. Funzionano bene fuori dagli schemi e sono un default perfettamente capace. L'uso degli UUID invece fa aggiungere un po' di attrito, sia quando si lavora con i valori (necessità di convertire in tipi binari, ecc.) sia in termini di prestazioni. Se questo piccolo inconveniente vale la pena avere un formato ID standardizzato dipende davvero dall'importanza che attribuisci alla portabilità e alle tue scelte architettoniche.

Sincronizzerai i dati tra diverse piattaforme di database? Migrerai i tuoi dati su una piattaforma diversa in futuro? Hai bisogno di generare ID all'esterno nel database, in altri sistemi o nel browser? Se non ora ad un certo punto in futuro? Gli UUID potrebbero valere la pena.

Aggiornamento agosto 2021

L'IEFT ha recentemente pubblicato una bozza di aggiornamento alle specifiche UUID che introdurrebbe alcune nuove versioni del formato.

In particolare, UUIDv6 e UUIDv7 sono basati su UUIDv1 ma capovolgono i blocchi timestamp in modo che i bit siano disposti dal più significativo al meno significativo. Ciò conferisce ai valori risultanti un ordine naturale che (più o meno) riflette l'ordine in cui sono stati creati. Le nuove versioni escludono anche i dati derivati ​​dall'indirizzo MAC dei server, affrontando una critica di lunga data agli UUID v1.

Ci vorrà del tempo prima che queste modifiche arrivino alle implementazioni, ma (IMHO) modernizzano e migliorano notevolmente il formato.