布尔类型
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的非法组合。 - 把“未设置”和“明确关闭”混为一谈;如果两者不同,就保留三种状态并在文档中定义。