Skip to content

sql-boolean-bit-operator

SQL 标准的 BOOLEAN(布尔)数据类型表示真值。它可以持有三种状态之一:TRUE(真)、FALSE(假)或 UNKNOWN(未知,由 NULL 表示)。这被称为三值逻辑,是 SQL 处理条件的基础。

这种数据类型非常适合表示二元状态的列,例如 is_active(是否激活)、has_been_shipped(是否已发货)或 is_premium_member(是否为高级会员)。

尽管 SQL 标准定义了 BOOLEAN 类型,但并非所有数据库都以相同的方式实现它。理解这些差异是编写可移植且正确代码的关键。

PostgreSQL 提供真正的 BOOLEAN 数据类型。它接受 TRUE、true、't'、'1' 等字面量表示真,以及 FALSE、false、'f'、'0' 表示假。它是最符合标准且最直接的实现。

CREATE TABLE feature_flags (
flag_name VARCHAR(50) PRIMARY KEY,
is_enabled BOOLEAN NOT NULL DEFAULT FALSE
);

MySQL 没有原生的 BOOLEAN 类型。相反,它提供 BOOL 和 BOOLEAN 作为 TINYINT(1) 的别名。在内部,它将 0 视为 FALSE,将任何非零整数视为 TRUE。关键字 TRUE 和 FALSE 只是 1 和 0 的别名。

CREATE TABLE settings (
setting_id INT PRIMARY KEY AUTO_INCREMENT,
send_notifications BOOLEAN DEFAULT TRUE
);
-- 这在内部被转换为:
-- send_notifications TINYINT(1) DEFAULT 1

Microsoft SQL Server 使用 BIT 数据类型来表示布尔值。它可以存储 1(表示真)、0(表示假)或 NULL。

CREATE TABLE Products (
ProductID INT PRIMARY KEY,
ProductName NVARCHAR(100),
IsDiscontinued BIT NOT NULL DEFAULT 0
);

在插入和查询时,最佳实践是直接使用布尔字面量(TRUE、FALSE)。这使得您的代码更具可读性和可移植性,即使底层系统将其转换为数字。

-- 这在 PostgreSQL、MySQL 和 SQL Server(在兼容设置下)中都适用
INSERT INTO feature_flags (flag_name, is_enabled) VALUES ('new_dashboard', TRUE);
INSERT INTO Products (ProductID, ProductName, IsDiscontinued) VALUES (101, 'Chai', FALSE);

过滤布尔列最可读且健壮的方法是使用 IS 运算符。避免直接与 1 或 0 进行比较。

-- 良好实践:清晰明确
SELECT * FROM feature_flags WHERE is_enabled IS TRUE;
-- 也常见,适用于所有主要 RDBMS
SELECT * FROM Products WHERE IsDiscontinued = FALSE;
-- 不良实践:可读性差,且对 NULL 值可能产生歧义
SELECT * FROM Products WHERE IsDiscontinued = 0;

要查找不为真的记录,您可以使用 IS NOT TRUE 或直接查询 IS FALSE。

-- 查找所有未停产的产品
SELECT * FROM Products WHERE IsDiscontinued IS FALSE;
-- 查找所有未启用的功能标志(包括 FALSE 和 NULL)
SELECT * FROM feature_flags WHERE is_enabled IS NOT TRUE;

在布尔上下文中,NULL 意味着“未知”。这与 FALSE 不同。例如,has_shipped 列可以是 TRUE(已发货)、FALSE(未发货)或 NULL(我们尚不知道发货状态)。

要专门查找布尔状态为未知的行,您必须使用 IS NULL。

-- 查找发货状态未知的订单
SELECT * FROM Orders WHERE has_shipped IS NULL;
-- 查找状态已知(TRUE 或 FALSE)的订单
SELECT * FROM Orders WHERE has_shipped IS NOT NULL;
  • 使用最合适的类型: 在 PostgreSQL 中使用 BOOLEAN,在 MySQL 中使用 BOOLEAN/TINYINT(1),在 SQL Server 中使用 BIT。
  • 优先使用 IS TRUE / IS FALSE: 在 WHERE 子句中使用这些运算符以获得最大清晰度和正确性,尤其是在可能存在 NULL 值的情况下。
  • 清晰命名列: 使用 is_、has_ 或 can_ 等前缀(例如 is_active、has_subscription)使列的布尔性质显而易见。
  • 设置 NOT NULL DEFAULT: 对于大多数布尔列,NULL 并非一个有用的状态。通常最好将其定义为 NOT NULL 并设置一个合理的默认值,例如 DEFAULT FALSE。