Wie speichere ich eine 1-Byte-Ganzzahl in PostgreSQL?

13

In der PostgreSQL-Dokumentation heißt es, dass ganzzahlige Datentypen entweder im Zwei-, Vier- oder Acht-Byte-Bereich gespeichert werden können. Eine der Spalten einer Tabelle in meiner Datenbank enthält einen Ein-Byte-Ganzzahlwert, und ich möchte, dass er in einem Ein-Byte-Datentyp gespeichert wird.

  1. Gibt es eine Erweiterung oder eine Möglichkeit, den Ein-Byte-Integer-Datentyp in PostgreSQL zu verwenden?
  2. Wie viele Bytes ist NUMERIC (1,0)?
ukll
quelle

Antworten:

14

Nein , in der Standardverteilung von Postgres gibt es keine 1-Byte-Ganzzahl. Alle integrierten numerischen Typen von Standard-Postgres belegen 2 oder mehr Bytes.

Erweiterung pguint

Aber ja , da ist die Erweiterung pguint , die von Peter Eisentraut, einem der Postgres- Kernentwickler , gepflegt wird. Es ist nicht Teil der Standarddistribution:

Zusätzlich zu verschiedenen vorzeichenlosen Ganzzahltypen bietet es auch die 1-Byte-Ganzzahl, nach der Sie suchen:

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)

Lesen Sie unbedingt das Kapitel "Diskussion" auf der verlinkten Seite, in dem mögliche Komplikationen erläutert werden. Sie müssen vorsichtig mit Typumwandlungen und numerischen Literalen sein, wenn Sie mehr ganzzahlige Typen einführen ...

Problemumgehung

Eine mögliche, einfache Problemumgehung wäre das Codieren von 1-Byte-Ganzzahlwerten als "char""interner" vereinfachter 1-Zeichen-Typ, der tatsächlich ein einzelnes Speicherbyte verwendet , Bytewerte einer vorzeichenbehafteten 1-Byte-Ganzzahl, wobei die obere Hälfte als dargestellt wird ASCII-Zeichen.

Sie können Werte im Bereich von -128 bis 127 codieren . Demo:

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

Es gibt mehrere Zeichen, die nicht zur Anzeige bestimmt sind. Codieren Sie also, bevor Sie speichern, und dekodieren Sie , bevor Sie ...

Denken Sie daran: "char"ist ein "interner" Typ, der für eine einfache und kostengünstige Aufzählung vorgesehen ist. Nicht offiziell für das konzipiert, was wir hier tun, und nicht auf andere RDBMS portierbar. Hierfür gibt es keine Garantien des Postgres-Projekts.

Meine anfänglichen Vorschläge basierten nachlässig auf der Annahme, dass wir den Bereich einer vorzeichenlosen 1-Byte-Ganzzahl (0-255) abdecken und textals Sprungbrett verwenden könnten . Evan wies auf die Fehler meines Weges hin: Das funktioniert nur für die Nummern 1 - 127 und schlägt für den Rest fehl. Verwenden Sie stattdessen den Ganzzahlbereich -128 bis 127 und setzen Sie zwischen "char"und integerdirekt um, um beide Probleme zu beheben.

Erwin Brandstetter
quelle