萬盛學電腦網

您现在的位置: 萬盛學電腦網 >> 程式設計 >  >> 資料庫 >> MySQL 教學

MySQL NULL 與空字串深度解析:儲存行為、統計差異與最佳實務

核心概念區別

  • NULL:代表「值不存在」、「未知」。佔用 1 位元標記(MyISAM)或無額外儲存(InnoDB 內部處理)。
  • 空字串 '':代表「值存在,但長度為 0」。佔用實際儲存空間(VARCHAR 1-2 位元組長度前綴)。

比喻:NULL = 從未分配房間;'' = 分配了房間但房間是空的。

實測行為差異(Timestamp 與 Varchar)

CREATE TABLE ceshi (ID INT, createDate TIMESTAMP, name VARCHAR(10));

-- 插入 NULL
INSERT INTO ceshi VALUES (1, NULL);        -- Timestamp 自動填入當前時間!NULL 不被存入
INSERT INTO ceshi (ID, name) VALUES (3, NULL); -- Varchar 正常存入 NULL

-- 插入空字串
INSERT INTO ceshi VALUES (2, '');          -- Timestamp 變 '0000-00-00 00:00:00'(無效日期)
INSERT INTO ceshi (name) VALUES ('');      -- Varchar 存入長度 0 的字串

統計函數表現差異

SELECT COUNT(name) FROM ceshi;  -- 僅計算非 NULL 值,空字串 '' 會被計入,NULL 不計入
-- 結果:1(只有那筆 '')
  • COUNT(*):計算行數,包含 NULL。
  • COUNT(col):計算該欄位非 NULL 行數。
  • SUM/AVG:忽略 NULL。

比較運算陷阱

SELECT '' = '';      -- TRUE (1)
SELECT NULL = NULL;  -- NULL (unknown),非 TRUE/FALSE
SELECT '' IS NULL;   -- FALSE
SELECT NULL IS NULL; -- TRUE

永遠使用 IS NULL / IS NOT NULL 判斷 NULL,切勿用 = / !=。

主鍵與唯一索引限制

  • 主鍵欄位不可為 NULL(標準 SQL 規範)。
  • 唯一索引允許多個 NULL(MySQL 視 NULL ≠ NULL),但僅允許一個空字串 ''。

字串連接與運算

SELECT CONCAT('abc', NULL);     -- 結果 NULL(任何與 NULL 運算結果為 NULL)
SELECT CONCAT('abc', '');       -- 結果 'abc'
SELECT 'abc' + NULL;            -- 數值運算隱性轉型,結果 NULL

最佳實務建議

  1. 語義明確才用 NULL:如「出生日期未知」用 NULL,「無中間名」用 ''。
  2. NOT NULL + DEFAULT:建表預設 NOT NULL DEFAULT '' 或 DEFAULT 0,避免 NULL 處理複雜度。
  3. 唯一業務鍵:若欄位允許「無值」,考慮用特殊標記值(如 'UNKNOWN')替代 NULL,確保唯一索引生效。
  4. 應用層統一:ORM/DAO 層統一處理 NULL/空字串轉換,避免業務邏輯散落判斷。
copyright © 萬盛學電腦網 all rights reserved