位掩码的整数和位(n)数据类型之间有啥区别吗?

Posted

技术标签:

【中文标题】位掩码的整数和位(n)数据类型之间有啥区别吗?【英文标题】:Is there any difference between integer and bit(n) data types for a bitmask?位掩码的整数和位(n)数据类型之间有什么区别吗? 【发布时间】:2012-04-17 00:02:15 【问题描述】:

我正在使用 PostgreSQL 数据库中的一个表,该表有几个布尔列来确定某些状态(例如publishedvisible 等)。我想创建一个状态列,它将以位掩码的形式存储所有这些值以及可能的新值。在这种情况下integerbit(n) 有什么区别吗?

这将是一个相当大的表,因为它存储用户通过 Web 界面创建的对象。所以我想我将不得不为这个专栏使用(部分)索引。

【问题讨论】:

【参考方案1】:

您可以将bit string functions 直接应用于位字符串,而无需从整数转换。

【讨论】:

【参考方案2】:

如果您只有几个变量,我会考虑保留单独的 boolean 列。

索引很容易。特别是indexes on expressions 和partial indexes。 查询条件易于编写和阅读且有意义。 布尔列占用 1 个字节(无对齐填充)。仅对于少数几个变量,这占用的空间最少。 与其他选项不同,boolean 列允许 NULL 在您需要时为各个位设置值。如果不这样做,您始终可以定义列 NOT NULL

如果您有多个完整变量但不超过 32 个,则integer可能效果最佳。 (或bigint 用于最多 64 个 变量。)

在磁盘上占用 4 个字节(可能需要对齐填充,具体取决于前面的列)。 完全匹配的索引非常快(= 运算符)。 处理单个值可能比varbitboolean 更慢/更不方便。

如果有更多变量,或者如果您想大量操作这些值,或者如果您没有巨大的表或磁盘空间/RAM 不是问题,或者如果您不确定选择什么,我会考虑bit(n) or bit varying(n) (short: varbit(n)

占用至少 5 个字节(或 8 个字节用于非常长的字符串)加上每组 8 位的 1 个字节(向上取整)。 您可以直接使用bit string functions and operators,也可以使用some standard SQL functions as well。

3 位 信息,单个 boolean 列需要 3 个字节,integer 需要 4 个字节(可能是额外的对齐填充)和 bit string 6 个字节(5 + 1)。

对于 32 位的信息,integer 仍然需要 4 个字节(+ 填充),bit string 占用相同 (5 + 4) 的 9 个字节,boolean 列占用32 字节。

要进一步优化磁盘空间,您需要了解 PostgreSQL 的存储机制,尤其是数据对齐。 More in this related answer.

This answer 关于如何转换类型 booleanbit(n)integer 也可能会有所帮助。

【讨论】:

非常感谢您的解释,这正是我所需要的!我想我会选择integer 专栏。

以上是关于位掩码的整数和位(n)数据类型之间有啥区别吗?的主要内容,如果未能解决你的问题,请参考以下文章

Postgres 中的位掩码

C中的位掩码

按位计数递增顺序遍历整数的每个位掩码[重复]

什么是位掩码?

PHP中基于位掩码获取数组值

当位掩码(标志)枚举变得太大时该怎么办