NULL(無值)與 ''(空字符串,有值但長度 0)在 MySQL 中語義、存儲、統計、索引、主鍵約束、時間戳默認值等方面差異顯著。本文通過實測案例逐項拆解。
NULL = NULL 為 UNKNOWN(非 TRUE)。'' = '' 為 TRUE。CREATE TABLE ceshi (id INT, createDate TIMESTAMP);
-- 1. 插入 NULL
INSERT INTO ceshi VALUES (1, NULL);
SELECT * FROM ceshi;
-- 結果:createDate = 當前系統時間(TIMESTAMP 默認 CURRENT_TIMESTAMP)
-- 2. 插入空字符串
INSERT INTO ceshi VALUES (2, '');
SELECT * FROM ceshi;
-- 結果:createDate = '0000-00-00 00:00:00'(零時間戳)
-- 3. VARCHAR 欄位插入 NULL vs ''
ALTER TABLE ceshi ADD name VARCHAR(10);
INSERT INTO ceshi (name) VALUES (NULL);
INSERT INTO ceshi (name) VALUES ('');
SELECT * FROM ceshi;
-- name 列顯示均為 NULL(客戶端顯示),但統計行為不同
SELECT COUNT(name) FROM ceshi;
-- 結果:1(僅計算非 NULL 值,'' 被計算,NULL 不計算)
SELECT COUNT(*) FROM ceshi;
-- 結果:4(計算所有行)
規則: 聚合函數(COUNT(col)、SUM、AVG 等)**忽略 NULL**,但**不忽略空字符串/零值**。
PRIMARY KEY 隱含 NOT NULL),可存 ''(字符串主鍵極不推薦)。WHERE col IS NULL 命中索引。-- MySQL
SELECT CONCAT('a', NULL, 'b'); -- NULL(任一參數為 NULL,結果為 NULL)
SELECT CONCAT('a', '', 'b'); -- 'ab'
-- SQL Server (T-SQL)
PRINT NULL + 'str'; -- NULL
PRINT '' + 'str'; -- 'str'
| 場景 | 推薦 | 理由 |
|---|---|---|
| 業務「無值」語義 | 用 NULL + IS NULL/IS NOT NULL | 語義清晰、聚合忽略、索引可查 |
| 業務「空值」語義(如非必填手機號) | 用 '' + NOT NULL DEFAULT '' | 避免 NULL 判斷、前端直接綁定、聚合計入 |
| 主鍵/唯一鍵 | NOT NULL + 自增/UUID | 主鍵不可 NULL,業務鍵避免 '' 衝突 |
| 時間戳創建時間 | TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP | 插入 NULL 會自動填充當前時間,插入 '' 會變零時間戳 |
| 可為 NULL 的外鍵 | FOREIGN KEY ... ON DELETE SET NULL | 利用 NULL 表示關聯斷開 |
WHERE col = NULL 永不命中 → ✅ WHERE col IS NULLWHERE col != 'val' 不包含 NULL 行 → ✅ WHERE col != 'val' OR col IS NULLNOT IN (subquery) 子查詢含 NULL 導致全表無結果 → ✅ NOT EXISTS 或 LEFT JOIN ... IS NULLORDER BY col DESC NULL 排在最前(MySQL 默認) → ✅ ORDER BY col IS NULL, col DESC 置後搞清 NULL 與 '' 的語義邊界,在建表定義 NOT NULL DEFAULT '' 或 NULL、查詢用 IS NULL、聚合預期行為一致,能消除一大類隱性 Bug。