MongoDB
 sql >> Base de Dados >  >> NoSQL >> MongoDB

Usando UUIDs em vez de ObjectIDs no MongoDB


O uso de UUIDs no Mongo é certamente possível e razoavelmente bem suportado. Por exemplo, os documentos do Mongo listam UUIDs como uma das opções comuns para o _id campo.

Considerações

  • Desempenho – Como outras respostas mencionam, os benchmarks mostram que os UUIDs causam uma queda no desempenho das inserções. No pior caso medido (de 10 a 20 milhões de documentos em uma coleção), eles são cerca de 2 a 3 vezes mais lentos – a diferença entre inserir 2.000 (UUID) e 7.500 (ObjectID) documentos por segundo. Esta é uma grande diferença, mas seu significado depende inteiramente do seu caso de uso. Você estará inserindo em lote milhões de documentos ao mesmo tempo? Para a maioria dos aplicativos que construí, o caso comum é inserir documentos individuais. Os mesmos benchmarks mostram que, para esse padrão de uso, a diferença é muito menor (6.250 -vs- 7.500; ~20%). Não é insignificante, mas também não é de arrasar.
  • Portabilidade – Muitas outras plataformas de banco de dados têm bom suporte a UUID, portanto, a portabilidade seria melhorada. Como alternativa, como os UUIDs são maiores (mais bits), é possível reempacotar um ObjectID na "forma" de um UUID. Essa abordagem não é tão boa quanto a portabilidade direta, mas oferece uma maneira de "mapear" entre ObjectIDs e UUIDs existentes.
  • Descentralização – Um dos grandes pontos de venda dos UUIDs é que eles são universalmente únicos. Isso torna prático gerá-los em qualquer lugar, de forma descentralizada (em contraste com, por exemplo, um valor de autoincremento, que requer uma fonte centralizada de verdade para determinar o valor "próximo"). É claro que os IDs de objeto Mongo também oferecem esse benefício. A diferença é que os UUIDs são baseados em um padrão de mais de 15 anos e suportados em (quase?) todas as plataformas, idiomas, etc. Isso os torna muito úteis se você precisar criar entidades (ou especificamente, conjuntos de relacionados entidades) em sistemas desconexos, sem interagir com o banco de dados. Você pode criar um conjunto de dados com IDs e chaves estrangeiras e, em seguida, gravar o gráfico inteiro no banco de dados em algum momento no futuro sem conflito. Embora isso também seja possível com os ObjectIDs do Mongo, encontrar código para gerá-los/trabalhar com o formato geralmente será mais difícil.

Correções


Ao contrário de algumas das outras respostas:
  • UUIDs têm suporte nativo ao Mongo – Você pode usar o UUID() funcione no Mongo Shell exatamente da mesma maneira que você usaria ObjectID(); para converter uma string UUID em um objeto BSON equivalente.
  • UUIDs não são especialmente grandes – Quando codificado usando o subtipo binário 0x04 eles são 128 bits, em comparação com 96 bits para ObjectIDs. (Se codificados como strings, eles serão ser bastante dispendioso, consumindo cerca de 288 bits.)
  • UUIDs podem incluir um carimbo de data/hora – Especificamente, UUIDv1 codifica um carimbo de data/hora com 60 bits de precisão, em comparação com 32 bits em ObjectIDs. Isso é mais de 6 ordens de magnitude de precisão, então nano-segundos em vez de segundos. Na verdade, pode ser uma maneira decente de armazenar carimbos de data e hora de criação com mais precisão do que o suporte a objetos Data Mongo/JS, no entanto...
    • A compilação em UUID() A função só gera UUIDs v4 (aleatórios), portanto, para aproveitar isso, você deve usar seu aplicativo ou driver Mongo para a criação de ID.
    • Ao contrário dos ObjectIDs, devido à forma como os UUIDs são agrupados, o carimbo de data/hora não fornece uma ordem natural. Isso pode ser bom ou ruim dependendo do seu caso de uso. (Novos padrões podem mudar isso; veja a atualização de 2021 abaixo.)
    • Incluir carimbos de data/hora em seus IDs às vezes é uma má ideia. Você acaba vazando o tempo de criação dos documentos em qualquer lugar que um ID seja exposto. (É claro que os ObjectIDs também codificam um carimbo de data/hora, então isso também é parcialmente verdadeiro para eles.)
    • Se você fizer isso com UUIDs v1 (em conformidade com especificações), também estará codificando parte do endereço MAC do servidor, que pode potencialmente ser usado para identificar a máquina. Provavelmente não é um problema para a maioria dos sistemas, mas também não é o ideal. (Novos padrões podem mudar isso; veja a atualização de 2021 abaixo.)

Conclusão


Se você pensar em seu Mongo DB isoladamente, os ObjectIDs são a escolha óbvia. Eles funcionam bem fora da caixa e são um padrão perfeitamente capaz. Usar UUIDs em vez disso faz adicionar algum atrito, tanto ao trabalhar com os valores (necessidade de converter para tipos binários, etc.) quanto em termos de desempenho. Se esse pequeno inconveniente vale a pena ter um formato de ID padronizado realmente depende da importância que você dá à portabilidade e às suas escolhas arquitetônicas.

Você sincronizará dados entre diferentes plataformas de banco de dados? Você migrará seus dados para uma plataforma diferente no futuro? Você precisa gerar IDs fora banco de dados, em outros sistemas ou no navegador? Se não agora em algum momento no futuro? UUIDs podem valer a pena.

Atualização de agosto de 2021


O IEFT publicou recentemente um rascunho de atualização para a especificação UUID que introduziria algumas novas versões do formato.

Especificamente, UUIDv6 e UUIDv7 são baseados em UUIDv1, mas invertem os pedaços de carimbo de data/hora para que os bits sejam organizados do mais significativo para o menos significativo. Isso dá aos valores resultantes uma ordem natural que (mais ou menos) reflete a ordem em que foram criados. As novas versões também excluem dados derivados do endereço MAC dos servidores, abordando uma crítica de longa data aos UUIDs v1.

Levará tempo para que essas mudanças fluam para as implementações, mas (IMHO) elas modernizam e melhoram significativamente o formato.