相信不少用了MySQL
好久的人,對這兩個字段屬性的概念還不是很清楚,通常會有如下疑問:mysql
not null
,爲何我能夠插入空值not null
的效率比null
高select * from table where column <> ''
仍是要用 select * from table wherecolumn is not null
呢。帶着上面幾個疑問,咱們來深刻研究一下null 和 not null
到底有什麼不同。
首先,咱們要搞清楚「空值」 和 「NULL」 的概念:sql
空值是不佔用空間的
NULL實際上是佔用空間的
,下面是來自於MYSQL官方的解釋:「NULL columns require additional space in the row to record whether their values are NULL. For MyISAM tables, each NULL column takes one bit extra, rounded up to the nearest byte.」函數
打個比方來講,你有一個杯子,空值表明杯子是真空的,NULL表明杯子中裝滿了空氣,雖然杯子看起來都是空的,可是區別是很大的。測試
搞清楚「空值」和「NULL」的概念以後,問題基本就明瞭了,咱們搞個例子測試一下:ui
CREATE TABLE `test` ( `col1` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL , `col2` VARCHAR( 10 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL ) ENGINE = MYISAM ;
插入數據:spa
INSERT INTO `test` VALUES (null,1);
mysql發生錯誤:rest
#1048 - Column 'col1' cannot be null
再來一條code
INSERT INTO `test` VALUES ('',1);
成功插入。
可見,NOT NULL 的字段是不能插入「NULL」的,只能插入「空值」,上面的問題1
也就有答案了。索引
對於問題2
,上面咱們已經說過了,NULL 其實並非空值,而是要佔用空間
,因此mysql在進行比較的時候,NULL 會參與字段比較,因此對效率有一部分影響。
並且B樹索引時不會存儲NULL值的,因此若是索引的字段能夠爲NULL,索引的效率會降低不少
。ip
咱們再向test的表中插入幾條數據:
INSERT INTO `test` VALUES ('', NULL); INSERT INTO `test` VALUES ('1', '2');
如今表中數據:
如今根據需求,我要統計test表中col1不爲空的全部數據,我是該用「<> ''」
仍是 「IS NOT NULL」 呢,讓咱們來看一下結果的區別。
SELECT * FROM `test` WHERE col1 IS NOT NULL
SELECT * FROM `test` WHERE col1 <> ''
能夠看到,結果迥然不一樣,因此咱們必定要根據業務需求,搞清楚究竟是要用那種搜索條件
。
MYSQL建議列屬性儘可能爲NOT NULL
長度驗證:注意空值的''之間是沒有空格的。
mysql> select length(''),length(null),length(' '); +------------+--------------+--------------+ | length('') | length(null) | length(' ') | +------------+--------------+--------------+ | 0 | NULL | 2 | +------------+--------------+--------------+
注意事項:
count()
統計某列的記錄數的時候,若是採用的NULL
值,系統會自動忽略掉,可是空值是會進行統計到其中的。 NULL
用IS NULL
或者 IS NOT NULL
, SQL
語句函數中可使用ifnull()
函數來進行處理,判斷空字符用=''
或者 <>''
來進行處理MySQL
特殊的注意事項,對於timestamp
數據類型,若是往這個數據類型插入的列插入NULL
值,則出現的值是當前系統時間。插入空值,則會出現 0000-00-00 00:00:00
is null
仍是=''
要根據實際業務來進行區分。