2015-03-24 10:38 GMT-03:00 Matheus Saraiva <[email protected]>:
> No meu ponto de vista bigint e bigserial são necessários quando, por
> exemplo, temos uma chave artificial que pode crescer de forma mais
> rápida que o normal.
> Além desse caso, quais seriam os outros casos em que eles são uteis?
>
>
Crescer de forma rápida tem dois pontos:
* O primeiro é, os registros antigos serão apagados de alguma forma? Se
forem, você pode usar a opção CYCLE ao criar sua SEQUENCE, assim sendo
quando atingir o limite de 2147483647 (2^31 - 1), o valor voltaria à 1.
* O segundo é quando realmente vários registros irão permanecer, ou não
consegue-se controlar os "id"s que ficarão. Nesse caso não tem jeito, se
você espera mais que 2^31 registros, então deves usar bigint/bigserial.
Em geral, bigint e int oferecem performance bem similares, apesar de bigint
ser o dobro do tamanho, veja alguns testes bem bacanas feitos pelo Depesz
em [1] (int = int4 e bigint = int8).
Agora, vamos à uma análise mais prática, assumindo o segundo caso, vamos
pensar num modelo onde são inseridos 10 linhas por segundo, com integer
iria exaurir em aprox. 6 anos e 10 meses, já com bigint em 29 bilhões de
anos. Agora, se considerássemos 1000 linhas por segundo, com integer
aguentaria apenas 24 dias, já bigint aguentaria 292 bilhões de anos. Por
curiosidade, 10000 linhas/segundo seria int=2 dias e bigint=29 milhões de
anos.
Essas contas de exemplo são só pra mostrar a magnitude que um bigint pode
chegar. Daí vem a dúvida, será que compensa usar "int" em casos de dúvida
só para economizar 4bytes por linha (que nem sempre são de fato
economizados devido à alinhamento)? Por outro lado, será que vale a pena
usar um UUID pensando que bigint *não vai aguentar* (vejam acima, milhões
de anos)?
Bem, se alguém quiser conferir testar, as contas que usei nas informações
acima foram (se alguém achar um erro, avisa aí):
=> SELECT txsec, justify_interval(((2^31) / txsec) * interval '1 sec') AS
int_usage, ((2^63) / txsec) / 31536000 AS bigint_usage FROM
(VALUES(10),(1000),(10000),(100000)) t(txsec);
txsec | int_usage | bigint_usage
--------+------------------------------------+------------------
10 | 6 years 10 mons 25 days 12:19:24.8 | 29247120867.7536
1000 | 24 days 20:31:23.648 | 292471208.677536
10000 | 2 days 11:39:08.3648 | 29247120.8677536
100000 | 05:57:54.83648 | 2924712.08677536
(4 rows)
> Aproveitando esse tema, alguém aqui na comunidade já atingiu o limite do
> integer com chaves artificiais? O que acontece e o que fazer?
>
Basta alterar o tipo:
ALTER TABLE tablename ALTER columname TYPE bigint;
O problema é que essa é uma operação custosa, pois é necessário reescrever
a tabela toda (apesar de ser possível fazer em lotes/batches), além disso é
necessário refazer as visões e funções para casar os tipos, caso tenham
dependências.
[1] http://www.depesz.com/2014/12/06/how-much-slower-are-numerics/
Atenciosamente,
--
Matheus de Oliveira
Analista de Banco de Dados
Dextra Sistemas - MPS.Br nível F!
www.dextra.com.br/postgres
_______________________________________________
pgbr-geral mailing list
[email protected]
https://listas.postgresql.org.br/cgi-bin/mailman/listinfo/pgbr-geral