Jak przechowywać jednobajtową liczbę całkowitą w PostgreSQL?

14

W dokumentacji PostgreSQL jest powiedziane, że typy danych liczb całkowitych mogą być przechowywane w przestrzeni dwu-, cztero- lub ośmiobajtowej. Jedna z kolumn tabeli w mojej bazie danych zawiera jednobajtową wartość całkowitą i chcę, aby była zapisana w jednobajtowym typie danych.

  1. Czy w PostgreSQL istnieje rozszerzenie lub sposób użycia jednobajtowego typu danych liczb całkowitych?
  2. Ile bajtów ma wartość NUMERYCZNA (1,0)?
ukll
źródło

Odpowiedzi:

16

Nie , w standardowej dystrybucji Postgres nie ma 1-bajtowej liczby całkowitej. Wszystkie wbudowane typy numeryczne standardowych Postgresów zajmują 2 lub więcej bajtów.

Przedłużka

Ale tak , istnieje kwestia rozszerzenia , którą utrzymuje Peter Eisentraut, jeden z głównych programistów Postgres. To nie jest część standardowej dystrybucji:

Oprócz różnych typów liczb całkowitych bez znaku, zapewnia także 1-bajtową liczbę całkowitą, której szukasz:

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)

Pamiętaj, aby przeczytać rozdział „Dyskusja” na linkowanej stronie, wyjaśniając możliwe komplikacje. Podczas wprowadzania większej liczby typów całkowitych musisz zachować ostrożność przy rzutowaniu czcionek i literałów liczbowych ...

Obejście

Możliwym, prostym obejściem byłoby zakodowanie 1-bajtowych wartości całkowitych jako "char"„wewnętrznego” uproszczonego 1-znakowego typu, który faktycznie wykorzystuje pojedynczy bajt pamięci , wartości bajtów podpisanej 1-bajtowej liczby całkowitej, górna połowa jest reprezentowana jako Znaki ASCII.

Można kodować wartości z zakresu od -128 do 127 . Próbny:

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

Istnieje kilka znaków nieprzeznaczonych do wyświetlenia. Więc koduj przed zapisaniem i dekoduj przed wyświetleniem ...

Pamiętaj: "char"to „wewnętrzny” typ przeznaczony do prostego i taniego wyliczania. Nie został oficjalnie zaprojektowany do tego, co tutaj robimy i nie jest przenośny dla innych RDBMS. Nie ma na to żadnych gwarancji ze strony projektu Postgres.

Moje wstępne sugestie były nieostrożnie oparte na założeniu, że obejmowalibyśmy zakres nieoznaczonej 1-bajtowej liczby całkowitej (0–255) i moglibyśmy użyć jej textjako odskoczni. Evan zwrócił uwagę na moje błędy: działa to tylko dla liczb 1–127, a dla pozostałych nie. Zamiast tego użyj zakresu liczb całkowitych od -128 do 127 i rzutuj pomiędzy "char"i integerbezpośrednio, aby naprawić oba problemy.

Erwin Brandstetter
źródło