浅探PostgreSQL中的bit类型

Bit,即比特,是二进制数字中的位。PostgreSQL 中提供了用于表示比特串数据类型bit。在PostgreSQL 中,bit 类型常见用法是bit(n),这里n表示bit串的长度。同时,也有不带(n)的bit和带双引号的”bit”。它们各自的含义是什么呢?又有什么联系和区别?简言之,不带“(n)”的bit表示bit(1),而带双引号的”bit”表示任意长度的位串。

我们通过下面的SQL语句创建一张表:

create table tb_bit ( bit_col bit, quoted_bit_col "bit", bit1_col bit(1) );

可以看到表 tb_bit 共有3列,他们的类型依次是不带(n)的bit,带引号且未指定长度的bit“”和bit(1),char(2)。bit(1)表示长度为1的位串,而另外两种类型是什么含义呢?

我们执行下列查询,从pg_attribute中查看这几列的属性:

select attrelid,attname,atttypid,attlen,atttypmod from pg_attribute where attrelid = tb_bit ::regclass::oid and attnum > 0

结果是:

attrelid | attname | atttypid | attlen | atttypmod ----------+----------------+----------+--------+----------- 392727 | bit_col | 1560 | -1 | 1 392727 | quoted_bit_col | 1560 | -1 | -1 392727 | bit1_col | 1560 | -1 | 1 (3 行记录)

可以看出 bit_col 的类型和长度同bit1_col的相同,因此可以断定,不带(n)的bit默认表示bit(1);quoted_bit_col 的atttypmod=-1。

PostgreSQL 官方文档对字段atttypmod的描述是:

对于一个固定尺寸的类型,typlen是该类型内部表示的字节数。对于一个变长类型,typlen为负值。-1表示一个"varlena"类型(具有长度字),-2表示一个以空值结尾的C字符串。

因此,带双引号的“bit”类型是变长的。

我们可以通过下面的实验验证。

执行如下查询:

select 11::bit;

查询结果:

bit ----- 1 (1 行记录)

再执行查询:

select 11::"bit";

查询结果:

bit ----- 11 (1 行记录)。

执行查询:

select 111::"bit";

查询结果:

bit ----- 111 (1 行记录)

可以看出,未指定长度且不带引号的bit类型默认为长度为1的位串,而带双引号的”bit”可以表示任意长度的位串。

经验分享 程序员 微信小程序 职场和发展