Is it possible to store a 1 byte number in Postgres?

后端 未结 7 2057
南方客
南方客 2021-02-04 00:26

I have 7 8-bit integer values per record that I want to store in Postgres. Pg doesn\'t offer a single byte integer type, SMALLINT, or 2 bytes, being the smallest integer datatyp

7条回答
  •  忘了有多久
    2021-02-04 01:06

    "char"

    This is a one-byte type in PostgreSQL that fits in the range of -128,127. From the docs,

    The type "char" (note the quotes) is different from char(1) in that it only uses one byte of storage. It is internally used in the system catalogs as a simplistic enumeration type.

    You can bias this towards [-128,127], by subtracting 128 from any input in the range of [0-255] before you write to the database, and adding it back on the output when you read from the database.

    -- works
    SELECT (-128)::"char", 127::"char";
    
    -- generates out of range
    SELECT (-128)::"char";
    SELECT 128::"char";
    
    -- Shifts to unsigned range.
    -- If you're going to be using "char"
    -- review the results of this query!
    SELECT
      x::int AS "inputUnsigned",
      chr(x) AS "extendedASCII",
      -- this is the "char" types representation for that input.
      signed::"char" AS "charRepresentation",
    
      signed     AS "inputUnsignedToSigned",
      signed+128 AS "inputUnsignedToSignedToUnsigned"
    FROM generate_series(1,255) AS gs(x)
    -- Here we map the input in the range of [0,255] to [-128,127]
    CROSS JOIN LATERAL ( VALUES (x::int-128) )
      AS v(signed);
    

    Small excerpt of the output

     inputUnsigned | extendedASCII | charRepresentation | inputUnsignedToSigned | inputUnsignedToSignedToUnsigned 
    ---------------+---------------+--------------------+-----------------------+---------------------------------
    ....
               190 | ¾             | >                  |                    62 |                             190
               191 | ¿             | ?                  |                    63 |                             191
               192 | À             | @                  |                    64 |                             192
               193 | Á             | A                  |                    65 |                             193
               194 | Â             | B                  |                    66 |                             194
               195 | Ã             | C                  |                    67 |                             195
               196 | Ä             | D                  |                    68 |                             196
    ...
    

    We use generate_series(1,255) only because chr(0) throws because you can't generate or output the ASCII NUL (PostgreSQL uses cstrings)

    pguint Extension

    Pguint is an extension that provides two one byte representations,

    • int1 (signed)
    • uint1 (unsigned)

提交回复
热议问题