跳到主要内容

布尔类型

boolean 只有 true、false 和 NULL 三种状态。前两者是明确的真假,NULL 表示未知或未提供;因此数据库中的布尔判断是三值逻辑,而不是简单的二值逻辑。

定义与输入​

CREATE TABLE features (
feature_id bigint PRIMARY KEY,
enabled boolean NOT NULL DEFAULT false,
rollout_complete boolean
);

PostgreSQL 接受 true、false、t、f、yes、no、on、off、1、0 等多种输入形式,输出通常是 t 或 f(客户端也可能显示为 true/false)。接口层应统一使用布尔值,不要依赖这些宽松别名。

NULL 与三值逻辑​

SELECT true AND NULL; -- NULL
SELECT false AND NULL; -- false
SELECT true OR NULL; -- true
SELECT NOT NULL; -- NULL

因此 WHERE enabled = true 不会返回 enabled IS NULL 的行。更直观的 PostgreSQL 写法是:

WHERE enabled IS TRUE
WHERE enabled IS NOT TRUE

IS TRUE 只匹配真值;IS NOT TRUE 同时匹配假值和 NULL。如果列业务上必须有答案,使用 NOT NULL,不要让每条查询重复猜测 NULL 的含义。

默认值不是约束​

DEFAULT false 只在插入时未提供列值时生效;显式插入 NULL 仍然会得到 NULL,除非列声明了 NOT NULL:

enabled boolean NOT NULL DEFAULT false

状态字段还可以配合 CHECK、触发器或状态机规则,限制某些组合不能同时出现。多个互斥状态不要堆叠很多布尔列,必要时使用枚举或独立状态列。

查询、索引与统计​

SELECT count(*) FILTER (WHERE enabled IS TRUE) AS enabled_count
FROM features;

布尔列可以建立部分索引,适合“只查询启用记录”的场景:

CREATE INDEX features_enabled_idx
ON features (feature_id)
WHERE enabled IS TRUE;

如果真值比例接近 50%,普通索引的收益可能有限;应以 EXPLAIN 和实际数据分布为准。

布尔值与用户输入​

不要把任意非空字符串都转换为 true。应用层应严格解析 JSON、表单或命令行输入,并拒绝 "enabled"、"yes please" 一类含义不明确的值。SQL 参数应绑定为布尔类型,而不是拼接字符串。

常见误区​

  • 用 0/1 的整数代替 boolean,让约束和语义变得含糊。
  • 以为 NOT NULL 会自动把缺失值变成 false;需要 DEFAULT false。
  • 用 = false 代替 IS NOT TRUE,漏掉 NULL 行。
  • 用多个布尔列表示互斥状态,造成 true/true 或全为 false 的非法组合。
  • 把“未设置”和“明确关闭”混为一谈;如果两者不同,就保留三种状态并在文档中定义。