關於資料庫,非空列有什麼好處嗎,和索引有什麼關係,為什麼盡量設置成非空呢?

資料庫設計的時候總是聽人說盡量非空(not-null),問一下非空有什麼性能上的好處?,和索引有什麼關係嗎,有時候非強制性的外鍵沒法設置成非空怎麼辦?非空列和查詢優化有什麼關係


NULL的引入使得原來的二值邏輯變成三值邏輯,除了True、False外,還引入了未知Unknown,例如比較X和Y是否相等:

三值邏輯的真值表也比較複雜:

NULL在查詢條件、外鍵和CHECK約束、唯一約束、GROUP BY、ORDER BY中的行為都是不一致的。 會造成令人迷惑的現象:

例如:

create table test(c1 int);

create unique index i1 on test(c1);

我們在c1列上建了一個唯一性約束的索引,理應不能插入重複的值,但是:

insert into test values(1);

insert into test values(NULL);

insert into test values(NULL);

select * from test;

會發現表中有三條記錄,其中兩條中c1列的值都是NULL。為什麼會發生這種現象?因為唯一性約束的檢查方法是對於新插入的數據與表中現有所有數據進行等於比較,如果返回為真,則說明表內有這個值,新插入的值違反了唯一性約束,禁止插入。而插入第二個NULL值時,無論是與1比較,還是與第一個 NULL比較,返回的布爾值都是Unknown,資料庫認為並未違反唯一約束,所以允許第二個NULL值得插入。但這種現象似乎與唯一性約束的要求相矛盾。

下面再看看利用比較謂詞的查詢:

select * from test where c1=1;

顯然返回一條記錄,與一般的預期相符。

而:

select * from test where not (c1=1);

這個查詢將不會返回任何記錄,因為 ,三個記錄計算這一謂詞的布爾值是False,Unknown,Unknown,沒有一個滿足True。

如果想要查詢c1列為NULL的值,必須利用特有的謂詞IS NULL,如:

select * from test where c1 is null;

將返回兩條c1為 NULL的記錄。

正是因為NULL對於完整性約束和查詢帶來一些不好的影響,所以一般建議最好表中沒有空值,在建表時加上非空約束。

至於NULL和索引的關係,主關鍵字自動帶有非空約束,而一般的索引列(如上面所創建的唯一性索引的列c1),是允許插入NULL的。


推薦閱讀:

如何寫一個輕量級分散式資料庫?
資料庫主從複製,讀寫分離,負載均衡,分庫分表分別表達的什麼概念?
NoSQL 能終結關係資料庫嗎?
mysql開發資料庫命名規範問題?
解釋一下關係資料庫的第一第二第三範式?

TAG:資料庫設計 | 索引 |