sql >> Databasteknik >  >> NoSQL >> MongoDB

Använder UUID istället för ObjectIDs i MongoDB

Att använda UUID i Mongo är verkligen möjligt och har någorlunda bra stöd. Till exempel, Mongo docs listar UUID som ett av de vanliga alternativen för _id fältet.

Överväganden

  • Prestanda – Som andra svar nämner visar riktmärken att UUID orsakar en prestandasänkning för inlägg. I värsta fall mätt (från 10 miljoner till 20 miljoner dokument i en samling) har de cirka 2-3 gånger långsammare – skillnaden mellan att infoga 2 000 (UUID) och 7 500 (ObjectID) dokument per sekund. Detta är en stor skillnad men dess betydelse beror helt på ditt användningsfall. Kommer du att satsa på miljontals dokument åt gången? För de flesta appar jag har byggt är det vanliga fallet att infoga enskilda dokument. Samma riktmärken visar att skillnaden är mycket för det användningsmönstret mindre (6 250 -vs- 7 500; ~20%). Inte oväsentlig.. men inte jordkrossande heller.
  • Bärbarhet – Många andra DB-plattformar har bra UUID-stöd så portabiliteten skulle förbättras. Alternativt, eftersom UUID är större (fler bitar) är det möjligt att packa om ett ObjectID till "formen" av ett UUID. Det här tillvägagångssättet är inte lika trevligt som direkt portabilitet, men det ger dig ett sätt att "karta" mellan befintliga ObjectIDs och UUIDs.
  • Decentralisering – En av de stora försäljningsargumenten med UUID är att de är universellt unika. Detta gör det praktiskt att generera dem var som helst, på ett decentraliserat sätt (i motsats till, till exempel ett automatiskt ökande värde, som kräver en centraliserad källa till sanning för att bestämma "nästa" värde). Naturligtvis bekänner Mongo Object ID också denna fördel. Skillnaden är att UUID är baserade på en 15+ år gammal standard och stöds på (nästan?) alla plattformar, språk etc. Detta gör dem mycket användbara om du någonsin behöver skapa enheter (eller specifikt uppsättningar av relaterade) enheter) i osammanhängande system, utan att interagera med databasen. Du kan skapa en datauppsättning med ID:n och främmande nycklar på plats, och sedan skriva in hela grafen i databasen någon gång i framtiden utan konflikt. Även om detta också är möjligt med Mongo ObjectIDs, kommer det ofta vara svårare att hitta kod för att generera dem/arbeta med formatet.

Rättelser

Tvärtemot vissa av de andra svaren:

  • UUID har inbyggt Mongo-stöd – Du kan använda UUID() fungerar i Mongo Shell exakt på samma sätt som du skulle använda ObjectID(); för att konvertera en UUID-sträng till motsvarande BSON-objekt.
  • UUID är inte särskilt stora – Vid kodning med binär undertyp 0x04 de är 128 bitar, jämfört med 96 bitar för ObjectIDs. (Om de är kodade som strängar kommer det vara ganska slösaktig, ta cirka 288 bitar.)
  • UUID kan innehålla en tidsstämpel – Specifikt kodar UUIDv1 en tidsstämpel med 60 bitars precision, jämfört med 32 bitar i ObjectID. Detta är över 6 storleksordningar mer precision, så nano-sekunder istället för sekunder. Det kan faktiskt vara ett anständigt sätt att lagra skapa tidsstämplar med mer noggrannhet än vad Mongo/JS Date-objekt stöder, men...
    • Inbyggnaden UUID() funktionen genererar endast v4 (slumpmässiga) UUID, så för att utnyttja detta måste du luta dig mot din app eller Mongo-drivrutin för att skapa ID.
    • Till skillnad från ObjectIDs ger tidsstämpeln dig inte en naturlig ordning på grund av hur UUID är uppdelade. Detta kan vara bra eller dåligt beroende på ditt användningsfall. (Nya standarder kan ändra detta; se 2021 års uppdatering nedan.)
    • Att inkludera tidsstämplar i dina ID är ibland en dålig idé. Det slutar med att du läcker den skapade tiden för dokument var som helst där ett ID exponeras. (Naturligtvis kodar ObjectIDs också för en tidsstämpel, så detta är delvis sant för dem också.)
    • Om du gör detta med (specifikationskompatibla) v1 UUID kodar du också en del av serverns MAC-adress, vilket potentiellt kan användas för att identifiera maskinen. Förmodligen inte ett problem för de flesta system men inte heller idealiskt. (Nya standarder kan ändra detta; se 2021 års uppdatering nedan.)

Slutsats

Om du tänker på din Mongo DB isolerat är ObjectIDs det självklara valet. De fungerar bra ur lådan och är en perfekt standard. Att använda UUID istället gör lägga till lite friktion, både när man arbetar med värdena (behöver konvertera till binära typer etc.) och när det gäller prestanda. Huruvida detta lilla besvär är värt att ha ett standardiserat ID-format beror verkligen på vikten du lägger vid portabilitet och dina arkitektoniska val.

Kommer du att synkronisera data mellan olika databasplattformar? Kommer du att migrera din data till en annan plattform i framtiden? Behöver du generera ID:n utanför databasen, i andra system eller i webbläsaren? Om inte nu någon gång i framtiden? UUID kan vara värt besväret.

Uppdatering augusti 2021

IEFT publicerade nyligen ett utkast till uppdatering av UUID-specifikationen som skulle introducera några nya versioner av formatet.

Specifikt är UUIDv6 och UUIDv7 baserade på UUIDv1 men vänder på tidsstämpelbitarna så att bitarna är ordnade från mest signifikant till minst signifikant. Detta ger de resulterande värdena en naturlig ordning som (mer eller mindre) återspeglar den ordning i vilken de skapades. De nya versionerna exkluderar även data som härrör från servrarnas MAC-adress, vilket tar itu med en långvarig kritik av v1 UUID.

Det kommer att ta tid för dessa ändringar att flyta igenom till implementeringar men (IMHO) de moderniserar och förbättrar formatet avsevärt.



  1. Fråga på Mongoid Hash Field

  2. Mongoose Unique index fungerar inte!

  3. Varför har Mongoose både scheman och modeller?

  4. Kan inte ansluta till MongoDB Atlas (queryTxt ETIMEOUT)