Bagaimana cara menyimpan integer satu byte di PostgreSQL?

14

Dalam dokumentasi PostgreSQL, dikatakan bahwa tipe data integer dapat disimpan dalam ruang dua, empat atau delapan byte. Salah satu kolom tabel dalam database saya berisi nilai integer satu-byte dan saya ingin disimpan dalam tipe data satu-byte.

  1. Apakah ada ekstensi atau cara untuk menggunakan tipe data integer satu byte di PostgreSQL?
  2. Berapa banyak byte yang NUMERIC (1,0)?
ukll
sumber

Jawaban:

16

Tidak , tidak ada integer 1-byte dalam distribusi standar Postgres. Semua tipe numerik bawaan dari Postgres standar menempati 2 atau lebih byte.

Pguint ekstensi

Tapi ya , ada pguint ekstensi , dikelola oleh Peter Eisentraut, salah satu pengembang inti Postgres. Itu bukan bagian dari distribusi standar:

Selain berbagai tipe integer yang tidak ditandatangani, ia juga menyediakan integer 1 byte yang Anda cari:

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)

Pastikan untuk membaca bab "Diskusi" di situs yang tertaut, menjelaskan kemungkinan komplikasi. Anda perlu berhati-hati dengan gips tipe dan literal angka saat memperkenalkan tipe bilangan bulat yang lebih banyak ...

Penanganan masalah

Solusi sederhana yang mungkin dilakukan adalah menyandikan nilai integer 1-byte sebagai "char", tipe 1-karakter sederhana "internal", yang benar-benar menggunakan penyimpanan byte tunggal , nilai byte dari integer 1-byte yang ditandatangani, bagian atas diwakili sebagai Karakter ASCII.

Anda dapat menyandikan nilai dalam kisaran -128 hingga 127 . Demo:

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

Ada beberapa karakter yang tidak dimaksudkan untuk tampilan. Jadi, enkode sebelum Anda menyimpan dan decode sebelum Anda menampilkan ...

Ingat: "char"adalah tipe "internal" yang dimaksudkan untuk penghitungan yang sederhana dan murah. Tidak dirancang secara resmi untuk apa yang kami lakukan di sini, dan tidak portabel untuk RDBMS lainnya. Tidak ada jaminan oleh proyek Postgres untuk ini.

Saran awal saya secara sembarangan didasarkan pada asumsi bahwa kami akan membahas kisaran integer 1-byte yang tidak ditandatangani (0-255) dan dapat digunakan textsebagai batu loncatan. Evan menunjukkan kesalahan dalam cara saya: yang hanya berfungsi untuk angka 1 - 127 dan gagal untuk sisanya. Alih-alih, gunakan rentang integer -128 hingga 127 dan gunakan antara "char"dan integerlangsung untuk memperbaiki kedua masalah.

Erwin Brandstetter
sumber