一、實驗
create table tbNotNull (
`id` INT (
11
) NOT NULL,
name varchar(
20
) NOT NULL
)
create table tbHaveNull (
`id` INT (
11
) NOT NULL,
name varchar(
20
) NULL
)
insert into tbNotNull values(
4
,
"zhaoliu"
), values(
2
,
"lisi"
),values(
3
,
"wangmazi"
),values(
1
,
"zhangsan"
),values(
2
,
"lisi2"
),values(
4
,
"zhaoliu2"
),values(
3
,
"wangmazi2"
)
insert into tbHaveNull values (
1
,
"zhaoliu_2_1"
),(
2
,
null
)
二、說明
1
、NOT IN子查詢在有NULL值的情況下返回永遠為空結果。
select name from tbNotNull where name not in (select name from tbHaveNull where id!=
1
)
2、如果在兩個欄位進行拼接:首先要各欄位進行非
null
判斷,否則只要任意一個欄位為空都會造成拼接的結果為
null
。
select CONCAT(
"1"
,
null
) from xxxx; -- 執行結果為
null
。
3、如果有 Null column 存在的情況下,count(Null column)需要格外注意,
null
值不會參與統計。
注意 Null 欄位的判斷方式, =
null
將會得到錯誤的結果。
4、注意 Null 欄位的判斷方式, =
null
將會得到錯誤的結果
5、Null 列需要更多的儲存空間:需要一個額外位元組作為判斷是否為 NULL 的標誌位
explain select * from tbNotNull where name=
'zhaoliu_2_1'
;
6、單列索引不存
null
值,複合索引不存全為
null
的值,如果列允許為
null
,可能會得到“不符合預期”的結果集(null的列如果是索引,則為null的列不進入索引裡)
-- 如果name允許為
null
,索引不儲存
null
值,結果集中不會包含這些記錄。所以,請使用not
null
約束以及預設值。
key_len 的計算規則和三個因素有關:資料型別、字元編碼、是否為 NULL
key_len 62 == 20*3(utf8 3位元組) + 2 (儲存 varchar 變長字元長度 2位元組,定長欄位無需額外的位元組)
key_len 83 == 20*4(utf8mb4 4位元組) + 1 (是否為 Null 的標識) + 2 (儲存 varchar 變長字元長度 2位元組,定長欄位無需額外的位元組)
所以說索引欄位最好不要為NULL,因為NULL會使索引、索引統計和值更加複雜,並且需要額外一個位元組的儲存空間。