2012-08-08 34 views
47

我見過很多次以下語法,在創建/修改DDL語句定義了一個列:SQL列定義:默認值和非空冗餘?

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault" 

的問題是:由於指定了默認值,是有必要還可以指定該列不應該接受NULL?換句話說,不DEFAULT呈現NOT NULL多餘?

回答

69

DEFAULT創建後,將在插入/更新語句沒有一個明確的值插入值。讓我們假設,你的DDL沒有足夠的NOT NULL約束:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" 

然後,你可以發出這些聲明

-- 1. This will insert "MyDefault" into tbl.col 
INSERT INTO tbl (A, B) VALUES (NULL, NULL); 

-- 2. This will insert "MyDefault" into tbl.col 
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, DEFAULT); 

-- 3. This will insert "MyDefault" into tbl.col 
INSERT INTO tbl (A, B, col) DEFAULT VALUES; 

-- 4. This will insert NULL into tbl.col 
INSERT INTO tbl (A, B, col) VALUES (NULL, NULL, NULL); 

另外,您還可以在UPDATE語句中使用DEFAULT,根據SQL-1992標準:

-- 5. This will update "MyDefault" into tbl.col 
UPDATE tbl SET col = DEFAULT; 

-- 6. This will update NULL into tbl.col 
UPDATE tbl SET col = NULL; 

請注意,並非所有數據庫都支持所有這些SQL標準語法。添加NOT NULL約束將導致錯誤,語句4, 6,而1-3, 5仍然是有效的語句。所以要回答你的問題:

不,NOT NULLDEFAULT不是多餘的。特別是,NOT NULL can have a tremendous impact on query performance as explained in this blog post here

8

即使使用默認值,也可以始終使用null覆蓋列數據。

NOT NULL限制不會讓你更新這一行它與null

+0

我想,這應當加以修改: 「NOT NULL限制不會讓你更新這一行它與空值在創建後」 中具有NOT NULL列的課程行可以更新,但它們不能用null作爲該列的值進行更新。 此外:我假設創建一行意味着插入一行。對於用NOT NULL指定的列,INSERT語句不能具有空值。 – makrom 2017-06-20 08:29:24

0

我會說不。

如果該列確實接受空值,那麼沒有什麼可以阻止您將空值插入字段,據我所知,默認值僅適用於創建新規則。

如果設置爲空,則不能在該字段中插入空值,因爲它會引發錯誤。

認爲它是防止死亡的自動防故障機制。

1

我的SQL老師說,如果你指定一個DEFAULT值和NOT NULLNULLDEFAULT應始終NOT NULLNULL之前表示。

像這樣:

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NOT NULL

ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NULL

+1

嗨,謝謝參與。但這並不能解決手頭的問題,而且這兩種排序都是完全有效的。我發現當手動編寫表格時,最後會將default設置爲最後,因爲NULL和NOT NULL值會更好地對齊。 – emragins 2017-05-17 17:02:33

+0

好吧,我想你也是對的。我不明白爲什麼我的課程明確地說我在答案上寫了什麼。 我知道我的答案並沒有真正解決這個問題,但我發現評論不會很好讀。 – 2017-05-18 10:50:56

+0

(主觀)最佳實踐和規則之間存在差異。擁有一致的風格並不是一個壞主意,但在這種特殊情況下,我個人更傾向於在DEFAULT之前不使用NOT NULL。無論如何,你也可以寫評論而不是答案,這將會更合適。 – makrom 2017-06-20 08:35:51