UUID x CUID x ULID

Descubra em detalhes o que significa cada um e qual deles é melhor você utilizar no seu banco de dados.

blog-image

UUID X ULID X CUID

Qual é a diferença entre eles ?

O que é UUID?

UUID, ou identificador único universal, é um rótulo de 128 bits usado para informações em sistemas operacionais. A probabilidade de um ID ser replicado não é zero, mas é tão próxima de zero que quando geramos um UUID, as chances de o identificador ser usado EM QUALQUER OUTRO lugar são quase nulas.

Um exemplo seria algo que se encaixa no formato

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx 
Exemplo: 123e4567-e89b-12d3-a456-426614174000.

O problema com o UUID

Ao pesquisar, encontrei um blog da PlanetScale, que é uma plataforma de dados serverless compatível com MySQL.

O título da postagem era "Por que escolhemos NanoIDs para a API da PlanetScale" e o post continua a falar sobre como os UUIDs são ótimos e tudo mais, pois é quase impossível gerar um identificador duplicado, no entanto, eles têm um grande problema: eles são muito grandes e ocupam muito espaço na URL.

Não adoramos URLs limpas e curtas? Ninguém gosta de ver um monte de dígitos e símbolos estranhos na sua URL. Citando o blog deles,

Eles ocupam muito espaço em uma URL: api.planetscale.com/v1/deploy-requests/7cb776c5-8c12-4b1a-84aa-9941b815d873

Tente dar dois cliques nesse ID para selecioná-lo e copiá-lo. Você não consegue. O navegador interpreta como 5 palavras diferentes.

Pode parecer algo insignificante, mas para construir um produto que os desenvolvedores adoram usar, precisamos nos preocupar com detalhes como esses.

O que é verdade! Se olharmos para a história do UUID, percebemos que ele nunca foi realmente feito para ser usado em aplicativos da web. Se tivermos um site como, por exemplo, o HasteBin, que depende da geração desses IDs curtos, de três letras, para compartilhar facilmente com as pessoas, isso causa um problema.

Sem falar no pior de tudo ele não é ordenável, ou seja, não é possível ordenar os registros por ele.

Ele ocupa mais espaço no disco, maioria dos servidores são 64 bits: UUID são chaves de 128 bits, logo precisam de no minimo 2 ciclos de CPU para serem processadas

O problema não é o uso do tipo UUID em si, mas sim utilizá-lo como chave primária em tabelas do banco de dados.

O que é CUID?

O CUID tem como objetivo resolver exatamente o problema que discutimos acima com os UUIDs. Citando o GitHub do CUID:

As aplicações web modernas têm requisitos diferentes das aplicações de apenas alguns anos atrás. Nossos identificadores exclusivos modernos têm uma lista mais rigorosa de requisitos que não podem ser atendidos por nenhuma versão existente das especificações GUID/UUID.

O CUID visa focar na escalabilidade horizontal (pois as aplicações atuais não são executadas em uma única máquina), desempenho, tamanho, segurança e portabilidade. O repositório do GitHub oferece uma análise mais detalhada dos problemas que isso visa resolver.

Eles são mais curtos, mas e quanto a colisões? Encontrei este benchmark online realizado em um gist do GitHub, mostrando que as chances de colisões ainda são extremamente baixas. Não foram encontradas colisões em 100 milhões de iterações!

Por exemplo o Prisma ORM (Meu ORM Preferido), o esquema do Prisma (em bancos de dados relacionais) pode gerar tanto um CUID quanto um UUID, dependendo das necessidades do seu aplicativo.

O que é ULID?

O ULID é um identificador único legível por humanos, seguro para ordenação, compacto e amigável para URL. Ele usa o tempo atual em milissegundos desde o Unix Epoch como parte de seu identificador, o que significa que ele é ordenável por data. Ele também usa caracteres codificados em base32, o que significa que é mais compacto do que o UUID.

Quando você gera um ID usando UUID, ele gera uma sequência de caracteres com 36 caracteres de comprimento, levando em consideração apenas a aleatoriedade ou o carimbo de data/hora.

Mas o ULID considera tanto a aleatoriedade quanto o carimbo de data/hora para gerar os IDs, e eles são codificados como sequências de caracteres com 26 caracteres (128 bits).

Exemplo de UUID: 01FHZXHK8PTP9FVK99Z66GXQTX

Os primeiros 10 caracteres do ULID representam o carimbo de data/hora e a segunda parte do ULID representa a aleatoriedade. Ambas essas partes são sequências codificadas em base 32 e representadas usando 48 bits e 80 bits, respectivamente.

Por exemplo, a decomposição do ULID acima ficaria assim:

01FHZXHK8PTP9FVK99Z66GXQTX 
> Timestamp (48 bits) - 01FHZXHK8P 
> Aleatoriedade (80 bits) - TP9FVK99Z66GXQTX 

Como já sabemos, os ULIDs podem ser ordenados. Essa característica dos ULIDs permite que os desenvolvedores gerenciem facilmente tarefas relacionadas a banco de dados, como ordenação, particionamento e indexação.

Por exemplo, você não precisa criar uma coluna extra para manter o registro do horário de criação. Em vez disso, você pode usar a representação de carimbo de data/hora do ULID para ordenar ou particionar os dados com base no horário de criação.

Conclusão

Qual deles devo usar?

Olha na minha humilde opinião depois de tudo aprensentado aqui, eu acho que o ULID é o melhor de todos, pois ele é mais curto que o UUID e mais seguro que o CUID, e ainda por cima é ordenável por data. Mas já deixando de utilizar o UUID e usando o CUID ou ULID você está no caminho certo.

Newsletter

Receba mensalmente uma curadoria de conteúdo com novidades sobre tecnologia, lançamento de produtos, tutoriais, artigos e design.


©2023   Roger Rocha