PostgreSQL:使用 BIT VARYING 列进行位掩码操作

PostgreSQL: Using BIT VARYING column for bitmask operations

我作为一名 C 程序员使用位掩码多年,我试图在 Postgres 中做一些类似的事情,但它没有像我预期的那样工作。所以这是一个包含 2 列的 table 定义:

    dummy 
    ( 
        countrymask  BIT VARYING (255) not null,  -- Yes it's a pretty wide bitmask
        countryname  CHARACTER VARYING NOT NULL, 
    );

因此,“虚拟”table 中的一些数据将是:

现在,SQL 到 return 阿尔巴尼亚、亚美尼亚和白俄罗斯与一个 select 一起使用面具是什么? (即“100010001”)

我以为会是这样的:

SELECT * FROM DUMMY WHERE (countrymask & (b'100010001')) <> 0;

但是我发现类型不匹配.. 我希望得到一些帮助。 而且,当类型转换被整理出来时,这会起作用吗?

您必须始终使用相同长度的位串,即 bit(255),并存储所有前导零。

如果你可以使用整数并执行

,这会更简单
WHERE countrymask & 273 <> 0

但是没有支持 & 运算符的 255 位整数类型。

无论如何,这样的查询永远不能使用索引,这对于像 dummy 这样的小 table 没有问题,但如果你想扫描更大的 table.

在某种程度上,该数据模型违反了第一范式,因为它在单个数据中存储了多个国家/地区代码。我认为你会更喜欢经典的关系模型:有一个国家 table 有一个用序列填充的数字主键,并使用映射 table 关联另一个 [=29= 中的行] 与多个国家。

另一种方法是将一行的国家/地区存储为国家/地区标识符数组 (bigint[])。然后,您可以使用“重叠”运算符 && 扫描 table 以查找在给定数组中包含任何国家/地区的行。这样的操作can be made fast with a GIN index.