我经常看到在创建/修改DDL语句中定义列的以下语法:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) NOT NULL DEFAULT "MyDefault"
问题是:既然指定了默认值,是否有必要还指定该列不接受NULL
?换句话说,DEFAULT
是否使NOT NULL
变得多余?
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);
另外,您也可以根据SQL-1992标准在UPDATE
语句中使用DEFAULT
:
-- 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
仍然是有效的语句。所以回答你的问题:不,它们不是多余的。
null
" 覆盖列数据。NOT NULL
" 限制将不允许您在使用 "null
" 值创建行后更新该行。我的SQL老师说,如果你同时指定了DEFAULT
值和NOT NULL
或NULL
,那么DEFAULT
应该始终在NOT NULL
或NULL
之前表达。
像这样:
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NOT NULL
ALTER TABLE tbl ADD COLUMN col VARCHAR(20) DEFAULT "MyDefault" NULL
CREATE TABLE t(id INT PRIMARY KEY, col INT DEFAULT 10);
-- we just inserted NULL into column with DEFAULT
INSERT INTO t(id, col) VALUES(1, NULL);
+-----+------+
| ID | COL |
+-----+------+
| 1 | null |
+-----+------+
DEFAULT ON NULL
:CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10);
-- same as
--CREATE TABLE t2(id INT PRIMARY KEY, col INT DEFAULT ON NULL 10 NOT NULL);
INSERT INTO t2(id, col) VALUES(1, NULL);
+-----+-----+
| ID | COL |
+-----+-----+
| 1 | 10 |
+-----+-----+
ALTER TABLE tbl ADD (col VARCHAR(20) DEFAULT ON NULL 'MyDefault');
ON NULL
如果您指定了 ON NULL 子句,则当后续的 INSERT 语句试图分配一个计算为 NULL 的值时,Oracle 数据库会分配 DEFAULT 列值。
当您指定 ON NULL 时,NOT NULL 约束和 NOT DEFERRABLE 约束状态会隐式指定。如果您指定了与 NOT NULL 和 NOT DEFERRABLE 冲突的内联约束,则会引发错误。
CREATE TABLE `test_table` (
`id` int NOT NULL AUTO_INCREMENT,
`age` int,
`name` VARCHAR(20) NOT NULL,
PRIMARY KEY (`id`)
);
NOT NULL
会防止你像下面这样操作:insert into test_table (age) value (10);
是的,在这种情况下会出现错误,但不是因为 NOT NULL
,而是因为你没有将 name
字段设置为 DEFAULT
,MySQL 会抱怨:Field 'name' doesn't have a default value
。
如果你像下面这样做:
insert into test_table (age, name) value (10, NULL);
MySQL 会报错 Column 'name' cannot be null
,这就是 NOT NULL
对我们的作用。
因此,NOT NULL
只是防止您向该字段插入 NULL
值,而 DEFAULT
允许您插入数据而不指定特定字段的值,它们是不同的。