在資料庫設計階段,關於欄位是否允許 NULL 值往往會引發團隊討論。SQL Server 領域權威專家 Kalen Delaney 針對此議題提出了三項核心建議,能幫助開發者避開常見陷阱:
SQL Server 為每筆記錄維護一個特殊的 Bitmap 來標記可為 NULL 的欄位是否真正儲存了 NULL。每次存取資料列時,引擎都必須解碼這個 Bitmap,這在高頻查詢場景下會產生不可忽視的 CPU 開銷。
允許 NULL 會迫使應用程式到處添加防禦性判斷邏輯(如 IS NULL、COALESCE、三值邏輯處理),這不僅增加代碼量,更容易因疏忽引入邏輯錯誤——例如 WHERE col <> 'value' 會自動過濾掉 NULL 行,導致查詢結果與直覺不符。
若欄位設為 NOT NULL 卻未提供 DEFAULT 值,若 INSERT 語句未顯式指定該欄位,SQL Server 會嘗試插入 NULL 而導致語句失敗。因此,為每個 NOT NULL 欄位指定合理的預設值(如空字串、0、預設日期等)是必要的配套動作。
NULL 值的比較行為取決於 ANSI_NULLS 選項:
IS NULL / IS NOT NULL。col = NULL 等同於 col IS NULL,col <> NULL 等同於 col IS NOT NULL。由於資料庫層級設定可能被會話層級的 SET ANSI_NULLS 覆蓋,且開發者通常無法控制 DBA 的全域設定,最穩健的做法是永遠使用標準的 IS NULL / IS NOT NULL 語法,完全忽略 ANSI_NULLS 設定。
建立測試資料表 t3 並插入兩筆資料(含一筆 NULL),分別在 ANSI_NULLS OFF 與 ON 下執行 SELECT * FROM t3 WHERE col = NULL:



圖示清楚顯示:OFF 時可查出 NULL 行,ON 時查無資料,證實語意差異。
資料表設計階段即決定:所有欄位預設 NOT NULL + 合理 DEFAULT 值。 若業務確實需要表達「未知/不適用」,改用具體語意值(如 -1、'N/A'、'1900-01-01')或獨立的旗標欄位,避免引入三值邏輯的複雜度。這樣既能消除儲存開銷,又能讓應用程式邏輯保持簡潔、可預測。