¿Cómo almacenar un entero de un byte en PostgreSQL?

14

En la documentación de PostgreSQL, se dice que los tipos de datos enteros se pueden almacenar en espacios de dos, cuatro u ocho bytes. Una de las columnas de una tabla en mi base de datos contiene un valor entero de un byte y quiero que se almacene en un tipo de datos de un byte.

  1. ¿Existe una extensión o una forma de usar el tipo de datos de entero de un byte en PostgreSQL?
  2. ¿Cuántos bytes es NUMÉRICO (1,0)?
ukll
fuente

Respuestas:

16

No , no hay un entero de 1 byte en la distribución estándar de Postgres. Todos los tipos numéricos integrados de Postgres estándar ocupan 2 o más bytes.

Extensión pguint

Pero , existe la extensión pguint , mantenida por Peter Eisentraut, uno de los principales desarrolladores de Postgres. No es parte de la distribución estándar:

Además de varios tipos de enteros sin signo, también proporciona el entero de 1 byte que está buscando:

int1 (signed 8-bit integer)
uint1 (unsigned 8-bit integer)
uint2 (unsigned 16-bit integer)
uint4 (unsigned 32-bit integer)
uint8 (unsigned 64-bit integer)

Asegúrese de leer el capítulo "Discusión" en el sitio vinculado, explicando las posibles complicaciones. Debe tener cuidado con los tipos de conversión y los literales numéricos al introducir más tipos enteros ...

Solución alterna

Una posible solución simple sería codificar valores enteros de 1 byte como "char"un tipo simplista "interno" de 1 carácter, que en realidad usa un solo byte de almacenamiento , valores de byte de un entero de 1 byte con signo, la mitad superior representada como Caracteres ASCII.

Puede codificar valores en el rango de -128 a 127 . Manifestación:

SELECT i
     , i::"char"
     , i::"char"::int
FROM   generate_series(-128,127) i;

Hay varios caracteres que no se deben mostrar. Así que codifique antes de almacenar y decodifique antes de mostrar ...

Recuerde: "char"es un tipo "interno" destinado a una enumeración simple y económica. No está oficialmente diseñado para lo que estamos haciendo aquí, y no es portátil para otros RDBMS. No hay garantías del proyecto Postgres para esto.

Mis sugerencias iniciales se basaron descuidadamente en el supuesto de que cubriríamos el rango de un entero de 1 byte sin signo (0-255) y que podríamos usar textcomo trampolín. Evan señaló los errores de mi manera: eso solo funciona para los números 1 a 127 y falla para el resto. En su lugar, use el rango entero -128 a 127 y eche entre "char"y integerdirectamente para solucionar ambos problemas.

Erwin Brandstetter
fuente