我想在Postgres中存储每个记录7个8位整数值.Pg不提供单字节整数类型,SMALLINT或2字节,是最小的整数数据类型.无论如何我可以存储我的7个8位数字并节省空间吗?
具有7个元素数组的数组类型是否更紧凑?或者,我应该对我的7个数字进行二进制表示(例如,在Perl中使用pack)并将其存储在单个bytea字段中吗?
还有其他建议吗?
Gre*_*ith 17
鉴于PostgreSQL中任何行的开销是23字节(HeapTupleHeaderData),如果你真的关心少量空间,那么你可能选择了错误的存储数据的方法.
无论如何,因为所有更复杂的类型都有自己的开销(bytea增加了4个字节的开销,例如,位串5到8),完成你要找的东西的唯一方法是使用bigint(8字节),以数字方式移动每个值并将结果进行OR运算.您可以使用位串操作来使代码更容易 - 计算为位串,然后在存储之前转换为bigint - 或者如果您希望速度更好,则只需手动乘法/添加.例如,以下是如何将两个字节一起存储为两个字节的结构,然后再将它们返回:
int2 = 256 * byte1 + byte2
byte1 = int2 / 256
byte2 = int2 % 256
Run Code Online (Sandbox Code Playgroud)
您可以将相同的想法扩展到以这种方式存储其中的7个.检索开销仍然很糟糕,但实际上你会在这个过程中节省一些空间.但与行标题相比并不是很多.
小智 6
有pg_catalog.char(另一种符号 - "char" )类型仅使用 1 个字节来存储其值。
select pg_column_size( 'A' );
pg_column_size
----------------
2
(1 row)
select pg_column_size( 'A'::"char" );
pg_column_size
----------------
1
(1 row)
Run Code Online (Sandbox Code Playgroud)
"char"这是 PostgreSQL 中的一个字节类型,适用于 -128,127 的范围。从文档中,
类型
"char"(注意引号)的不同之处char(1)在于它只使用一个字节的存储空间。它在系统目录中作为一种简单的枚举类型在内部使用。
您可以将其偏向 [-128,127],方法是在写入数据库之前从 [0-255] 范围内的任何输入中减去 128,并在您从数据库中读取时将其添加回输出。
-- 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);
Run Code Online (Sandbox Code Playgroud)
输出的小摘录
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
...
Run Code Online (Sandbox Code Playgroud)
我们使用generate_series(1,255)只因为chr(0)throws 因为你不能生成或输出 ASCII NUL(PostgreSQL 使用 cstrings)
pguint 延期Pguint是一个扩展,它提供两个单字节表示,
int1 (签)uint1 (未签名)| 归档时间: |
|
| 查看次数: |
11385 次 |
| 最近记录: |