CodeGym /Cursos /SQL SELF /Geração de identificadores únicos

Geração de identificadores únicos

SQL SELF
Nível 16 , Lição 0
Disponível

Quando os computadores começaram a se conectar em rede de verdade, apareceu um problema simples mas bem tenso: como garantir que dois dispositivos diferentes, em lugares diferentes do mundo, não vão gerar o mesmo identificador?

Pensa só: dois servidores, um em Tóquio e outro em Berlim, criando identificadores pra objetos de forma independente. Se eles gerarem o mesmo ID — os dados podem se misturar, sobrescrever e o sistema pode cair.

Foi aí que, nos anos 90, na época do boom dos sistemas distribuídos e protocolos de rede, a galera da Microsoft e da Open Software Foundation (OSF) teve a ideia do GUIDGlobally Unique Identifier, ou identificador globalmente único.

O GUID (no padrão ISO é chamado de UUID, Universally Unique Identifier) é um número de 128 bits, que parece mais ou menos assim:

550e8400-e29b-41d4-a716-446655440000

É tipo uma impressão digital digital: tão longo e aleatório que a chance de colisão (dois IDs iguais) é praticamente zero.

Ele é criado usando:

  • tempo,
  • números aleatórios,
  • endereço MAC do dispositivo (nas versões antigas),
  • e até funções hash criptográficas.

Por que isso era importante? Porque o GUID permitiu criar identificadores únicos sem servidor central, sem coordenação, sem locks e sem atrasos. Isso salvou a vida de:

  • bancos de dados distribuídos,
  • protocolos de rede,
  • sistemas de documentos,
  • e claro, APIs modernas.

UUID no PostgreSQL

GUID/UUID é usado em tudo quanto é lugar — de PostgreSQL até serviços em nuvem. Eles são os construtores invisíveis da internet moderna: sem eles, juntar o mundo seria bem mais difícil.

No fim das contas, é só um número aleatório bem grande de 16 bytes, escrito em hexadecimal. Só um número inteiro bem grandão.

Esse tipo de dado é perfeito se você precisa garantir unicidade dos valores no sistema todo, sem depender de um gerador centralizado de IDs. Isso é especialmente útil em sistemas distribuídos ou quando os dados são gerados em servidores diferentes.

Por que não usar só INTEGER?

Parece que não faz sentido usar UUID se dá pra usar um número auto-incremental como identificador, né? Bora ver:

Unicidade global: Se seu banco rodar em vários servidores, garantir unicidade com INTEGER é complicado. Com UUID isso é resolvido.

Segurança e esconder dados: UUID é bem mais difícil de adivinhar do que um número sequencial. Isso diminui o risco de vazar info por IDs previsíveis (tipo /users/1, /users/2).

Sistemas distribuídos: Se os dados são gerados em partes diferentes do sistema, um INTEGER auto-incremental não serve sem uma sincronização complicada.

Outra vantagem do UUID — é padrão, suportado em várias linguagens de programação e sistemas de armazenamento.

Vantagens de usar UUID

Os principais pontos positivos:

  • Unicidade: garante que o identificador é único, mesmo se os dados forem criados em servidores ou sistemas diferentes.
  • Flexibilidade: dá pra usar como chave primária, chave estrangeira e outras paradas.
  • Escalabilidade: ótimo pra trabalhar com bancos de dados distribuídos.

Mas o UUID também tem seus pontos negativos:

  • Tamanho: UUID ocupa mais espaço na memória (16 bytes) do que INTEGER (4 bytes).
  • Leitura: é mais difícil de ler e decorar.

Gerando UUID no PostgreSQL

Função nativa gen_random_uuid()

No PostgreSQL a partir da versão 13 tem a função nativa gen_random_uuid() pra gerar UUID aleatório. Essa função retorna um identificador único, que você pode usar como valor pra coluna do tipo UUID.

Exemplo:

SELECT gen_random_uuid();

Resultado:

d17fc23b-22e5-4fcb-bf86-1b4c766d77b7

Confere se a extensão pgcrypto tá instalada (pra PSQL 1-12)

Nas versões antigas do PostgreSQL (antes da 13) a função gen_random_uuid() só aparece depois de instalar a extensão pgcrypto. Se no trampo te obrigarem a usar, dá pra resolver rodando:

CREATE EXTENSION IF NOT EXISTS "pgcrypto";

Assim você pode usar a geração de UUID aleatório.

Usando UUID como chave estrangeira

UUID é bem prático pra criar relações entre tabelas. Imagina que você tem uma tabela de usuários:

id name email
d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 Alice alice@example.com
a1d3e15a-abc1-4b51-a320-2d4c859f7467 Bob bob@example.com
3c524998-5c24-4e73-836d-a4c6bb3cafcd Charlie charlie@example.com

Criando a tabela orders

Bora criar a tabela orders, onde user_id vai ser a chave estrangeira apontando pro id da tabela users.

order_id user_id order_date
1a5b7d9c-b1a2-4f8e-9e7a-0a1111111111 d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 2024-10-15 10:00:00
2b6c8e0d-c2b3-5a9f-af8b-1b2222222222 a1d3e15a-abc1-4b51-a320-2d4c859f7467 2024-10-15 10:05:00
3c7d9f1e-d3c4-6baf-bc9c-2c3333333333 3c524998-5c24-4e73-836d-a4c6bb3cafcd 2024-10-15 10:10:00
4d8eaf2f-e4d5-7cb0-cdab-3d4444444444 d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 2024-10-15 10:15:00
5e9fb030-f5e6-8dc1-debc-4e5555555555 a1d3e15a-abc1-4b51-a320-2d4c859f7467 2024-10-15 10:20:00

O campo user_id tá ligado ao campo id da tabela users, o que permite criar relações entre usuários e seus pedidos.

Selecionando dados com JOIN

Vamos ver como os dados das tabelas users e orders se relacionam:

SELECT 
    u.id AS user_id, 
    u.name, 
    o.order_id, 
    o.order_date 
FROM users u
JOIN orders o ON u.id = o.user_id;

Resultado:

user_id name order_id order_date
d17fc23b-22e5-4fcb-bf86-1b4c766d77b7 Alice a1d3e15a-abc1-4b51-a320-2d4c859f7467 2024-10-20 12:34:56

Cenários principais de uso do UUID

Identificadores de usuários e pedidos: em sistemas distribuídos, onde os dados podem vir de várias fontes.

Marcação pra API: UUID é muito usado em REST API pra identificar entidades.

Sincronização global de dados: tipo quando os dados vêm de vários servidores.

Erros comuns e particularidades

Tentar gerar UUID na mão: melhor usar funções nativas como gen_random_uuid() pra não dar ruim.

Uso exagerado: não use UUID onde um INTEGER auto-incremental já resolve. Tipo em tabelas locais que nunca vão escalar.

Tamanho: UUID ocupa mais espaço, o que pode impactar a performance das queries, principalmente nos índices.

Comentários
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION