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”可以表示任意长度的位串。