O tipo de dados uuid
é perfeitamente adequado para a tarefa. Ele só ocupa 16 bytes em oposição a 37 bytes de memória RAM para o varchar
ou text
representação. (Ou 33 bytes no disco, mas o número ímpar exigiria preenchimento em muitos casos para torná-lo efetivamente 40 bytes.) E o uuid
tipo tem mais algumas vantagens.
Exemplo:
SELECT md5('Store hash for long string, maybe for index?')::uuid AS md5_hash
Detalhes e mais explicações:
Você pode considerar outras funções de hash (mais baratas) se não precisar do componente criptográfico do md5, mas eu usaria o md5 para o seu caso de uso (principalmente somente leitura).
Uma palavra de advertência : Para o seu caso ( immutable once written
), uma PK funcionalmente dependente (pseudo-natural) é adequada. Mas o mesmo seria uma dor onde as atualizações text
são possíveis. Pense em corrigir um erro de digitação: o PK e todos os índices dependentes, colunas do FK dozens of other tables
e outras referências também teriam que mudar. Inchaço de tabela e índice, problemas de bloqueio, atualizações lentas, referências perdidas, ...
Se text
puder mudar na operação normal, uma PK substituta seria uma escolha melhor. Sugiro uma bigserial
coluna (intervalo -9223372036854775808 to +9223372036854775807
- são nove quintilhões duzentos e vinte e três quatrocentos trezentos e setenta e dois trilhões trinta e seis algo bilhões ) para valores distintos billions of rows
. Em qualquer caso, pode ser uma boa ideia : 8 em vez de 16 bytes para dezenas de colunas e índices do FK!). Ou um UUID aleatório para cardinalidades muito maiores ou sistemas distribuídos. Você sempre pode armazenar o md5 (as uuid
) adicionalmente para encontrar rapidamente linhas na tabela principal a partir do texto original. Relacionado:
Quanto à sua consulta :
Para abordar o comentário de @ Daniel : Se você preferir uma representação sem hífens, remova os hífens para exibição:
SELECT replace('90b7525e-84f6-4850-c2ef-b407fae3f271', '-', '')
Mas eu não me incomodaria. A representação padrão está correta. E o problema realmente não é a representação aqui.
Se outras partes devem ter uma abordagem diferente e jogar cordas sem hífens na mistura, isso também não é um problema. O Postgres aceita várias representações de texto razoáveis como entrada para a uuid
. A documentação :
O PostgreSQL também aceita as seguintes formas alternativas de entrada: uso de dígitos maiúsculos, o formato padrão entre parênteses, omitindo alguns ou todos os hífens, adicionando um hífen após qualquer grupo de quatro dígitos. Exemplos são:
A0EEBC99-9C0B-4EF8-BB6D-6BB9BD380A11
{a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11}
a0eebc999c0b4ef8bb6d6bb9bd380a11
a0ee-bc99-9c0b-4ef8-bb6d-6bb9-bd38-0a11
{a0eebc99-9c0b4ef8-bb6d6bb9-bd380a11}
Além disso, a md5()
função retorna text
, você usaria decode()
para converter bytea
e a representação padrão disso é:
SELECT decode(md5('Store hash for long string, maybe for index?'), 'hex')
\220\267R^\204\366HP\302\357\264\007\372\343\362q
Você precisaria encode()
novamente para obter a representação de texto original:
SELECT encode(my_md5_as_bytea, 'hex');
Para completar, os valores armazenados como bytea
ocupariam 20 bytes na RAM (e 17 bytes no disco, 24 com preenchimento ) devido à sobrecarga internavarlena
, o que é particularmente desfavorável para o tamanho e o desempenho de índices simples.
Tudo funciona a favor de um uuid
aqui.