NULL và Index - Giá trị đặc biệt cần đặc biệt chú ý
NULL trong SQL nghĩa là “không biết” (unknown), KHÔNG phải “rỗng” hay “zero”.
Behavior quan trọng
NULL = NULL → NULL (không phải TRUE!)
NULL != NULL → NULL (không phải TRUE!)
NULL > 5 → NULL
NULL + 10 → NULL
-- Bất kỳ phép tính nào với NULL đều trả về NULL
-- Trong context WHERE, NULL được coi như FALSENULL trong sort order
SQL standard không quy định - mỗi database tự quyết:
- MySQL: NULL đứng trước (nhỏ nhất)
- PostgreSQL: NULL đứng sau (lớn nhất)
Kiểm soát vị trí NULL trong ORDER BY: MySQL dùng ORDER BY country IS NULL, country ASC; PostgreSQL dùng NULLS FIRST / NULLS LAST.
NULL và Index
IS NULLhoạt động giống equality check - database nhảy thẳng đến block NULL entries → mọi nguyên tắc index áp dụng bình thường:WHERE supervisor_id IS NULL AND name = 'Huy' -- Index (supervisor_id, name) → Fast lookup NULL → tìm 'Huy' → hiệu quả!IS NOT NULLhoạt động giống inequality - phải scan tất cả entries khác NULL. Nếu 95% nhân viên có supervisor → match 95% rows → database bỏ qua index.
Cái bẫy ngầm: NULL trong so sánh != (bug LOGIC, không chỉ performance)
-- Bảng users 1000 rows, 50 rows có country = NULL
SELECT * FROM users WHERE country != 'VN';
-- Bạn nghĩ: trả về tất cả trừ VN → 900 rows?
-- Thực tế: 850 rows! 50 rows NULL bị BỎ SÓT
-- Vì: NULL != 'VN' → NULL → coi như FALSE → không có trong kết quảCách fix:
-- Cách dài:
WHERE country != 'VN' OR country IS NULL
-- MySQL (NULL-safe equality operator):
WHERE NOT(country <=> 'VN')
-- PostgreSQL:
WHERE country IS DISTINCT FROM 'VN'Liên quan
- Unique Constraint và NULL - NULL ≠ NULL phá vỡ ràng buộc UNIQUE
- Inequality và Index - IS NOT NULL cùng bản chất
- Query Tips hữu ích - NULLIF tránh division by zero