Estou trabalhando em um projeto que está usando o formato de chave do instagram .
TL;DR IDs inteiros de 64 bits.
Eles serão usados para pesquisas, e também gostamos deles para classificar e agrupar, pois eles serão classificados naturalmente pelo tempo de criação.
Os valores estão entre 2^63 e 2^64, então (apenas) grande demais para caber dentro de um arquivo BIGINT
.
Portanto, parece que nossas opções de armazenamento são numeric(20)
ou varchar
. varchar
não é tão ideal, já que teríamos que zerá-los para que a classificação funcione, mas haveria um impacto no desempenho ao usar um numérico para pesquisas?
Odeio ser o capitão óbvio neste, mas o Instagram generosamente fornece uma função que você vinculou que armazena as chaves como
bigint
.Na verdade, eles estão usando o PostgreSQL. A partir dessa função, você pode ver que eles estão retornando um arquivo
bigint
. Então certamente você pode armazenar o resultado dessa função embigint
. Como uma nota especial, essa provavelmente não é a função que eles estão usando. Essa função provavelmente tem uma assinatura mais assim,Sabemos disso porque codificar um fragmento de
5
não é tão útil e eles parecem indicar que estão usando essa funcionalidade. Então, nesse id de blog, eles se gabam de que seu ID comprometeTeste rápido em seu código,
Decompondo o ID
Agora vamos jogar. Para o extra sexy, podemos criar funções auxiliares que obtêm os componentes internos do ID. Caso você queira saber o fragmento que o Instagram está usando ou seu carimbo de data/hora interno.
Brincando, vamos pegar um id de teste.
Retorna o seguinte,
Lançando nosso próprio domínio de ID do Instagram
Você pode até criar um explícito
DOMAIN
sobre o tipo se quiser realmente limpar isso. É assim que eu pessoalmente armazenaria isso, observe que fiz algumas modificações adicionais.COMMENTS
- sempre uma boa prática.IMMUTABLE
insta5.next_id
requer um estilhaço explícito.Vamos largar o que tínhamos,
E recomeçar,
Tudo funciona como antes, mas agora você pode
Esta é provavelmente a melhor solução que você pode obter tímido de uma implementação C, e você provavelmente não deseja gerar um
insta5id
nunca. Esse é o trabalho deles. ;)Como outro aparte importante, você provavelmente nunca quer fazer isso. Não siga pelo exemplo. É para isso que serve o
uuid
tipo , e você deve usá-lo em vez de enrolar manualmente o seu. Especificamente, isso é estranhamente semelhante auuid_generate_v1()
inuuid-ossp
, que armazena um MAC (shard) e timestampnumeric
é maior e mais lento quebigint
(8 bytes) em todos os aspectos. Infelizmente, como você disse,bigint
não é grande o suficiente. O máximo é2^63-1
=9223372036854775801
, 19 dígitos decimais.varchar
outext
(mesma coisa internamente) são maiores e mais lentos, ainda. Além disso, os tipos de caracteres são sobrecarregados comCOLLATION
regras, a menos que sejam explicitamente definidos sem.(Mas 13/21 bytes no disco.) Veja:
db<>fique aqui
numeric
economiza espaço adicional para zeros à direita, o quetext
não pode acontecer.numeric
não permite que não-números sejam armazenados e impõe alguma sanidade fora da caixa.Perante as suas exigências, escolha
numeric
e nunca olhe para trás.Relacionado:
Ou você pode instalar a extensão
pguint
de Peter Eisentraut, um dos principais hackers do projeto Postgres.Certifique-se de ler o leia- me primeiro. A extensão fornece vários tipos inteiros adicionais (a maioria deles não assinados). Você pode apenas extrair
uint8
(inteiro não assinado de 64 bits) e descartar o resto para evitar a superlotação do sistema de tipos.O intervalo de a
bigint
é -9223372036854775808 a +9223372036854775807 , que é -2^63 a 2^63-1 — ou 2^64 inteiros distintos. O intervalo de seus identificadores é de 2 ^ 63 inteiros distintos, então eles se encaixam perfeitamente em umbigint
, desde que você não se importe com um deslocamento:dbfiddle aqui
Meu exemplo usa um deslocamento de -9223372036854775809 (-2^63+1), mas você pode escolher qualquer deslocamento que não estoure o
bigint
.Portanto, você precisará usar
numeric
ao apresentar as chaves e ao aplicar o deslocamento, mas não para armazenar as chaves ou operações como classificação.