Pular para o conteúdo
Obtani
Desenvolvimento Web

UUID v4 ou v7: Qual Usar como Chave Primária

6 min de leitura

Quer o número agora? Gere UUIDs nas versões 4 e 7, em lote, no formato que você precisa e com cópia num clique.

Gerador de UUID

Por anos houve uma escolha única quando o assunto era identificador distribuído: UUID versão 4, 122 bits sorteados, sem informação nenhuma embutida. Desde maio de 2024, quando a RFC 9562 substituiu a antiga RFC 4122, existe uma alternativa oficial pensada exatamente para o caso em que o UUID vira chave primária de uma tabela: a versão 7.

A diferença entre as duas cabe numa frase. O v4 sorteia tudo. O v7 usa os primeiros 48 bits para o horário de criação, em milissegundos, e sorteia o resto. Como o UUID é escrito da esquerda para a direita, a consequência é direta: a ordem alfabética de uma lista de UUIDs v7 é a ordem em que eles foram criados.

Por que a ordenação muda o custo do banco de dados

Quase todo banco relacional guarda o índice da chave primária numa estrutura chamada B-tree. Ela é uma árvore de páginas ordenadas, e o custo de inserir uma chave nova depende muito de onde ela cai.

Quando as chaves chegam em ordem crescente — um id sequencial, uma data, um UUID v7 — cada registro novo entra no fim. O banco toca sempre a mesma página, que já está na memória, e só ocasionalmente cria uma página nova. O índice fica denso e a escrita é barata.

Quando as chaves chegam em ordem imprevisível, como num UUID v4, cada inserção cai num ponto aleatório da árvore. Isso produz três efeitos que se somam:

EfeitoO que acontece
Escritas espalhadasCada inserção toca uma página diferente, e o banco precisa buscá-la do disco
Divisão de páginasUma página cheia no meio da árvore se parte em duas, cada uma pela metade
Índice inchadoPáginas pela metade significam mais páginas para a mesma quantidade de linhas

O terceiro efeito é o que se nota depois, quando alguém repara que o índice ocupa mais espaço do que a tabela. Não é um problema de correção: o banco funciona. É um problema de custo, e ele cresce com o volume.

Se o seu sistema tem milhares de linhas, nada disso importa. Se tem dezenas de milhões e recebe escrita o tempo todo, importa bastante — e é exatamente a situação em que alguém escolheu UUID em vez de um id sequencial, porque precisava gerar identificadores em várias máquinas sem coordenar.

O que o v7 cobra em troca

Não existe almoço grátis. Os 48 bits de horário são legíveis por qualquer pessoa que tenha o identificador. Basta ler os doze primeiros dígitos hexadecimais e converter: você sabe o milissegundo em que aquele registro nasceu.

Isso é irrelevante na maioria dos casos e é um problema sério em alguns:

  • Identificador exposto em URL pública. Se o endereço de um pedido, de um documento ou de um perfil carrega o UUID, o horário de criação vira informação pública. Em alguns contextos isso é só curiosidade; em outros, é vazamento.
  • Contagem por inferência. Com vários UUIDs v7 do mesmo sistema, dá para estimar o ritmo de criação de registros — quantos pedidos por hora, quantos cadastros por dia. É o tipo de métrica que um concorrente gosta de ter.
  • Correlação temporal. Dois identificadores criados no mesmo milissegundo provavelmente vieram da mesma operação. Isso pode ligar coisas que você preferia manter separadas.

A saída prática mais comum é usar os dois: v7 na chave primária interna, que nunca sai do banco, e v4 no identificador público, aquele que aparece na URL. Custa uma coluna a mais e resolve os dois problemas de uma vez.

O detalhe que quase ninguém implementa direito

Há uma armadilha na versão 7 que só aparece quando você gera vários identificadores de uma vez — que é, justamente, o caso de inserir um lote de registros.

UUIDs criados no mesmo milissegundo têm o mesmo carimbo de tempo. Se os bits restantes forem puro sorteio, a ordem entre eles é aleatória, e a vantagem do v7 desaparece exatamente onde ela mais importaria. Um lote de mil linhas inseridas no mesmo instante volta a ser um lote de chaves embaralhadas.

A RFC 9562 trata disso na seção 6.2 e oferece três métodos. O mais simples e mais usado é o contador dedicado: reservar 12 bits logo depois do carimbo de tempo, sorteá-los uma vez a cada milissegundo novo e incrementar a cada identificador gerado dentro daquele milissegundo. O resultado é uma sequência estritamente crescente, com a imprevisibilidade preservada nos 62 bits seguintes.

Vale conferir se a biblioteca que você usa faz isso. Muitas implementações de UUID v7 sorteiam os 74 bits e pronto — funcionam, passam em qualquer teste de formato, e entregam ordenação só entre milissegundos diferentes.

O gerador de UUID do Obtani implementa o contador de 12 bits. Gere vinte identificadores na versão 7 e confira: eles saem em ordem estritamente crescente, porque todos nascem no mesmo milissegundo.

E se eu já uso v4 em produção?

Migrar chave primária é uma das operações mais caras que existem, e raramente vale a pena só pela fragmentação do índice. Antes de considerar, meça: veja o tamanho real do índice comparado ao da tabela e o tempo médio de inserção. Se os números estão confortáveis, não mexa.

Quando faz sentido migrar, o caminho usual não é converter o que existe, e sim passar a gerar v7 nos registros novos. Como as duas versões têm o mesmo formato de 128 bits e o mesmo layout de escrita, elas convivem na mesma coluna sem qualquer alteração de esquema. Os registros antigos continuam espalhados; os novos passam a entrar em ordem. Com o tempo, a proporção resolve sozinha a parte que importa.

O que não muda em nenhuma das duas versões: a unicidade é probabilística. Nenhum gerador de UUID consulta nada nem sabe o que já foi gerado — nem o seu, nem o da outra máquina. A probabilidade de repetição é baixa a ponto de ser desprezível na prática, mas se o seu sistema não pode conviver com uma colisão em hipótese alguma, o que garante isso é a restrição de unicidade no banco de dados, não a confiança no formato.

Resumo da escolha

  • Use v7 quando o UUID for chave primária de uma tabela que recebe muita escrita, quando você quiser ordenação cronológica sem coluna extra, e quando o identificador não for exposto.
  • Use v4 quando o identificador aparecer em URL pública, quando o horário de criação for informação sensível, ou quando você simplesmente não tem um problema de índice para resolver.
  • Use os dois quando der: v7 por dentro, v4 por fora.

E, em qualquer um dos casos, lembre que UUID não é segredo. Ele identifica; não protege. Para isso existe outra ferramenta.

Leia também