Cada linha em uma tabela tem uma coluna ctid
de sistema do tipo tid
que representa a localização física da linha:
create table t(id serial); insert into t default values; insert into t default values;
select ctid , id from t;
ctid | Eu iria :---- | -: (0,1) | 1 (0,2) | 2
dbfiddle aqui
Qual é a melhor maneira de obter apenas o número da página ctid
no tipo mais apropriado (por exemplo integer
, bigint
ou numeric(1000,0)
)?
A única maneira que consigo pensar é muito feia.
db<>mexa aqui
@bma sugeriu algo semelhante em seu comentário . Aqui está um ...
Justificativa do tipo
ctid
é do tipotid
(identificador de tupla), chamadoItemPointer
no código-fonte da linguagem C. O manual:Ênfase em negrito minha. E:
Um bloco tem 8 KB em instalações padrão. O tamanho máximo da tabela é de 32 TB . Segue-se logicamente que os números de bloco devem acomodar pelo menos um máximo de (fixado pelo comentário de @Daniel):
O que caberia em um arquivo
integer
. Em uma investigação mais aprofundada, descobri no código-fonte que ...Ênfase em negrito minha. O que confirma o primeiro cálculo:
Postgres usa inteiro assinado e, portanto, é um pouco curto. Ainda não consegui definir se a representação do texto é deslocada para acomodar o número inteiro com sinal. Até que alguém possa esclarecer isso, eu voltaria para
bigint
, que funciona de qualquer maneira.Elenco
Não há elenco registrado para o
tid
tipo no Postgres 9.3 (ainda verdadeiro no Postgres 13):Você ainda pode transmitir para
text
. Existe uma representação de texto para cada tipo no Postgres :A representação de texto corresponde à de um ponto, que consiste em dois
float8
números, cuja conversão é sem perdas.Você pode acessar o primeiro número de um ponto com índice 0. Cast to
bigint
. Voilá.atuação
Fiz um teste rápido no Postgres 9.4 em uma tabela com 30k linhas (melhor de 5) com algumas expressões que me vieram à mente, incluindo a sua original:
int
em vez debigint
, principalmente irrelevante para o propósito do teste. Acabei repetindo o teste no Postgres 13bigint
em uma tabela com 50k linhas. Os resultados são basicamente os mesmos!A conversão se
t_tid
baseia em um tipo composto definido pelo usuário, como @Jake comentou.A essência disso: a conversão tende a ser mais rápida do que a manipulação de strings. Expressões regulares são caras. A solução acima é a mais curta e rápida.