Come memorizzare numeri interi a un byte in PostgreSQL?


14

Nella documentazione di PostgreSQL, si dice che i tipi di dati interi possono essere memorizzati in uno spazio a due, quattro o otto byte. Una delle colonne di una tabella nel mio database contiene un valore intero a un byte e voglio che sia memorizzato in un tipo di dati a un byte.

  1. Esiste un'estensione o un modo per utilizzare il tipo di dati intero a un byte in PostgreSQL?
  2. Quanti byte è NUMERIC (1,0)?

Risposte:


16

No , non esiste un numero intero a 1 byte nella distribuzione standard di Postgres. Tutti i tipi numerici incorporati di Postgres standard occupano 2 o più byte.

Pguint di estensione

Ma , c'è il pguint di estensione , gestito da Peter Eisentraut, uno dei principali sviluppatori di Postgres. Non fa parte della distribuzione standard:

Oltre a vari tipi di numeri interi senza segno, fornisce anche l'intero di 1 byte che stai cercando:

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)

Assicurati di leggere il capitolo "Discussione" sul sito collegato, spiegando possibili complicazioni. È necessario prestare attenzione con i cast di tipi e i letterali numerici quando si introducono più tipi di numeri interi ...

Soluzione

Una possibile, semplice soluzione sarebbe quella di codificare i valori interi a 1 byte come "char", un tipo "interno" semplicistico a 1 carattere, che utilizza effettivamente un singolo byte di memoria , i valori byte di un intero con segno a 1 byte, la metà superiore rappresentata come Caratteri ASCII.

È possibile codificare valori nell'intervallo da -128 a 127 . demo:

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

Esistono diversi caratteri non destinati alla visualizzazione. Quindi codifica prima di archiviare e decodificare prima di visualizzare ...

Ricorda: "char"è un tipo "interno" destinato all'enumerazione semplice ed economica. Non ufficialmente progettato per quello che stiamo facendo qui, e non portatile per altri RDBMS. Per questo il progetto Postgres non ha garanzie.

I miei suggerimenti iniziali erano incautamente basati sul presupposto che avremmo coperto l'intervallo di un intero di 1 byte senza segno (0-255) e che potremmo usare textcome trampolino di lancio. Evan ha sottolineato gli errori sulla mia strada: funziona solo per i numeri 1 - 127 e fallisce per il resto. Utilizzare invece l'intervallo intero compreso tra -128 e 127 e eseguire il cast tra "char"e integerdirettamente per risolvere entrambi i problemi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.