PostgreSQL:使用位可变列进行位掩码操作

PostgreSQL:使用位可变列进行位掩码操作,sql,postgresql,select,bitmask,Sql,Postgresql,Select,Bitmask,作为一名C程序员,多年来我一直在使用位掩码,现在我正试图在Postgres中做类似的事情,但它并没有像我预期的那样工作。下面是一个包含两列的表定义: dummy ( countrymask BIT VARYING (255) not null, -- Yes it's a pretty wide bitmask countryname CHARACTER VARYING NOT NULL, ); 因此,“虚拟”表中的一些数据是

作为一名C程序员,多年来我一直在使用位掩码,现在我正试图在Postgres中做类似的事情,但它并没有像我预期的那样工作。下面是一个包含两列的表定义:

    dummy 
    ( 
        countrymask  BIT VARYING (255) not null,  -- Yes it's a pretty wide bitmask
        countryname  CHARACTER VARYING NOT NULL, 
    );
因此,“虚拟”表中的一些数据是:

现在,使用掩码返回阿尔巴尼亚、亚美尼亚和白俄罗斯的SQL是什么??(即“100010001”)

我以为会是这样的:

SELECT * FROM DUMMY WHERE (countrymask & (b'100010001')) <> 0;
从虚拟对象中选择*,其中(countrymask和(b'100010001'))0;
但是我有一个类型不匹配。。我想得到一些帮助。
但是,当类型转换被分类时,这也会起作用吗?

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

如果可以使用整数并执行

WHERE countrymask & 273 <> 0
其中countrymask&273 0
但是没有255位的整数类型支持
&
运算符

无论如何,这样的查询永远不会使用索引,这对于像
dummy
这样的小表来说是没有问题的,但是如果您想扫描更大的表,这可能是个问题

在某种程度上,该数据模型违反了第一个范式,因为它在一个数据中存储了多个国家代码。我认为使用一个经典的关系模型会让您更高兴:拥有一个国家表,该表的数字主键填充了一个序列,并使用一个映射表将另一个表中的行与多个国家关联起来


另一种方法是将行的国家存储为国家标识符数组(
bigint[]
)。然后,您可以使用“重叠”操作符
&&
扫描表中具有给定数组中任何国家/地区的行。这样的操作。

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

如果可以使用整数并执行

WHERE countrymask & 273 <> 0
其中countrymask&273 0
但是没有255位的整数类型支持
&
运算符

无论如何,这样的查询永远不会使用索引,这对于像
dummy
这样的小表来说是没有问题的,但是如果您想扫描更大的表,这可能是个问题

在某种程度上,该数据模型违反了第一个范式,因为它在一个数据中存储了多个国家代码。我认为使用一个经典的关系模型会让您更高兴:拥有一个国家表,该表的数字主键填充了一个序列,并使用一个映射表将另一个表中的行与多个国家关联起来


另一种方法是将行的国家存储为国家标识符数组(
bigint[]
)。然后,您可以使用“重叠”操作符
&&
扫描表中具有给定数组中任何国家/地区的行。这种操作。

关系数据库不是C程序。使用位掩码并不适合关系模型。正确规范化的模型将更易于使用
create table dummy(id integer主键,country_name varchar(100))
为了提高性能,我们一直在对表进行非规范化处理,因此使用雪花模式等。该数据库中有10个数百万行,我们希望根据需要选择不同的国家/地区集。因此,这套系统包含了所有国家的名称——大约200个独立国家。使用标准的“IN”子句速度非常慢,尤其是使用国家名称(文本)时,会强制进行多个表扫描。任何关于这方面的想法都是受欢迎的。我不认为IN子句会导致多个表扫描。关系数据库不是C程序。使用位掩码并不适合关系模型。正确规范化的模型将更易于使用
create table dummy(id integer主键,country_name varchar(100))
为了提高性能,我们一直在对表进行非规范化处理,因此使用雪花模式等。该数据库中有10个数百万行,我们希望根据需要选择不同的国家/地区集。因此,这套系统包含了所有国家的名称——大约200个独立国家。使用标准的“IN”子句速度非常慢,尤其是使用国家名称(文本)时,会强制进行多个表扫描。欢迎对此发表意见。我不认为IN子句会导致多个表扫描。非常好的回答,谢谢Laurenz。我面临的问题是,该表有2000多万行,其中有一个“country”列。应用程序/用户可以选择世界上任何一个国家,如上面的示例所示,应用程序将返回所有与之对应的行。在SQL中使用“IN”子句会导致多个表扫描。所以比特屏蔽似乎是解决这个问题的一种方法。任何关于更好机制的想法都是受欢迎的。我在答案中添加了一个建议。阵列可以做你想做的。谢谢Laurenz,我想这就是我需要的答案。作为参考,在我读了你的文章之后,我来到这个页面查看一个实现。非常好的回应,谢谢Laurenz。我面临的问题是,该表有2000多万行,其中有一个“country”列。应用程序/用户可以选择世界上任何一个国家,如上面的示例所示,应用程序将返回所有与之对应的行。在SQL中使用“IN”子句会导致多个表扫描。所以比特屏蔽似乎是解决这个问题的一种方法。任何关于更好机制的想法都是受欢迎的。我在答案中添加了一个建议。阵列可以做你想做的。谢谢Laurenz,我想这就是我需要的答案。作为参考,在我读了你的文章之后,我来到这个页面查看一个实现。