首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >可以在Postgres中存储一个1字节的数字吗?

可以在Postgres中存储一个1字节的数字吗?
EN

Stack Overflow用户
提问于 2010-06-22 11:49:13
回答 7查看 14.9K关注 0票数 23

我想要存储在Postgres中,每个记录有7个8位整数值。Pg不提供单字节整数类型SMALLINT或2字节,这是最小的整数数据类型。有没有什么办法可以存储我的7个8位数字并节省空间?

具有7元素数组的数组类型会更紧凑吗?或者,我是否应该对我的7个数字进行二进制表示(例如,在Perl中使用pack )并将其存储在一个bytea字段中?

还有其他建议吗?

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-06-22 20:30:40

考虑到PostgreSQL中任何行的开销都是23 bytes (HeapTupleHeaderData),如果您真的关心这么少的空间,那么您可能选择了错误的数据存储方式。

无论如何,因为所有更复杂的类型都有它们自己的开销(bytea增加了4个字节的开销,例如,位串5到8),实现所需的唯一方法是使用bigint (8字节),对每个值进行数值移位并对结果进行OR运算。您可以使用bit string operations来简化代码--计算为位字符串,然后在存储之前转换为bigint --或者如果您希望速度更快,也可以手动进行乘法/加法。例如,下面是如何将两个字节一起存储到一个双字节结构中,然后再将它们取回:

代码语言:javascript
复制
int2 = 256 * byte1 + byte2
byte1 = int2 / 256
byte2 = int2 % 256

你可以将同样的想法扩展到以这种方式存储其中的7个。检索开销仍然很大,但您实际上已经在此过程中节省了一些空间。但是仅仅相对于行头来说并不是很多。

票数 19
EN

Stack Overflow用户

发布于 2011-10-25 21:34:51

有一种pg_catalog.char (另一种符号- "char“)类型,它只使用一个字节来存储它的值。

代码语言:javascript
复制
select pg_column_size( 'A' );
pg_column_size
----------------
              2
(1 row)

select pg_column_size( 'A'::"char" );
pg_column_size
----------------
              1
(1 row)
票数 6
EN

Stack Overflow用户

发布于 2018-03-19 06:15:59

"char"

这是PostgreSQL中的单字节类型,适合于-128,127的范围。来自the docs,

类型"char" (请注意引号)与char(1)的不同之处在于它的只使用一个字节的存储空间。它在系统目录中作为一种简单的枚举类型在内部使用。

您可以在写入数据库之前从0-255范围内的任何输入中减去128,然后在从数据库读取时将其添加回输出,从而使其偏向-128,127。

代码语言:javascript
复制
-- 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);

输出的小摘录

代码语言:javascript
复制
 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
...

我们使用generate_series(1,255)只是因为chr(0)会抛出,因为您不能生成或输出ASCII (PostgreSQL使用NUL )

pguint扩展

Pguint是提供两个单字节表示的扩展,

  • int1 (signed)
  • uint1 (未签名)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3090138

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档