Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  Data Types  /  Data Type Default Values

13.6 数据类型默认值

数据类型指定可以有明确或隐式的默认值。

在数据类型指定中,DEFAULT value 子句明确地指示了一个列的默认值。例如:

CREATE TABLE t1 (
  i     INT DEFAULT -1,
  c     VARCHAR(10) DEFAULT '',
  price DOUBLE(16,2) DEFAULT 0.00
);

SERIAL DEFAULT VALUE 是一种特殊情况。在整数列的定义中,它是 NOT NULL AUTO_INCREMENT UNIQUE 的别名。

一些明确DEFAULT 子句处理方面是版本相关的,以下描述了这些方面。

DEFAULT 子句中指定的默认值可以是一个字面常量或一个表达式。除了一个例外,需要将表达式默认值括在圆括号内以区分它们与字面常量默认值。例如:

CREATE TABLE t1 (
  -- literal defaults
  i INT         DEFAULT 0,
  c VARCHAR(10) DEFAULT '',
  -- expression defaults
  f FLOAT       DEFAULT (RAND() * RAND()),
  b BINARY(16)  DEFAULT (UUID_TO_BIN(UUID())),
  d DATE        DEFAULT (CURRENT_DATE + INTERVAL 1 YEAR),
  p POINT       DEFAULT (Point(0,0)),
  j JSON        DEFAULT (JSON_ARRAY())
);

特殊情况是,对于TIMESTAMPDATETIME列,你可以将CURRENT_TIMESTAMP函数作为默认值,without enclosing parentheses。见第13.2.5节,“TIMESTAMP和DATETIME的自动初始化和更新”

BLOBTEXTGEOMETRYJSON数据类型只能在将值写作表达式时指定默认值,即使该表达式值是字面量:

  • 这是允许的(字面量默认指定为表达式):

    CREATE TABLE t2 (b BLOB DEFAULT ('abc'));
  • 这产生错误(字面量默认不指定为表达式):

    CREATE TABLE t2 (b BLOB DEFAULT 'abc');

expression默认值必须遵守以下规则。如果一个表达式包含禁止的构造,会出现错误。

  • 字面量、内置函数(确定性和非确定性)和操作符是允许的。

  • 子查询、参数、变量、存储函数和可加载函数不允许。

  • expression默认值不能依赖具有AUTO_INCREMENT属性的列。

  • 一个表列的表达式默认值可以引用其他表列,除了对生成列或具有表达式默认值的列之外,该引用只能是该表定义中的早于当前列的列。也就是说,表达式默认值不能包含对生成列或具有表达式默认值的列的前向引用。

    ALTER TABLE 语句也遵守同样的顺序约束。如果结果表中包含对生成列或具有表达式默认值的列的前向引用,语句将失败。

Note

如果一个表达式默认值的某个组件依赖于 SQL 模式,那么在不同的使用场景下可能会出现不同结果,除非在所有使用场景中都保持相同的 SQL 模式。

CREATE TABLE ... LIKECREATE TABLE ... SELECT,目标表将保留原始表的表达式默认值。

如果表达式默认值引用非确定性函数,任何导致表达式被评估的语句都不是安全的语句基于语句复制。包括像INSERTUPDATE 等语句。在这种情况下,如果二进制日志禁用,语句将被执行为正常。如果启用二进制日志且binlog_format 设置为 STATEMENT,语句将被记录和执行,但写入错误日志警告信息,因为副本可能会分歧。设置binlog_formatMIXEDROW,语句将被执行为正常。

当插入新行时,表达式默认值的列可以通过省略列名或指定列名为DEFAULT(与字面值默认值相同)来插入:

mysql> CREATE TABLE t4 (uid BINARY(16) DEFAULT (UUID_TO_BIN(UUID())));
mysql> INSERT INTO t4 () VALUES();
mysql> INSERT INTO t4 () VALUES(DEFAULT);
mysql> SELECT BIN_TO_UUID(uid) AS uid FROM t4;
+--------------------------------------+
| uid                                  |
+--------------------------------------+
| f1109174-94c9-11e8-971d-3bf1095aa633 |
| f110cf9a-94c9-11e8-971d-3bf1095aa633 |
+--------------------------------------+

然而,使用DEFAULT(col_name) 指定命名列的默认值,只允许在有字面值默认值的列上,不允许在表达式默认值的列上。

不所有存储引擎都允许表达式默认值。对于不允许的,一个ER_UNSUPPORTED_ACTION_ON_DEFAULT_VAL_GENERATED错误发生。

如果默认值计算结果与声明的列类型不同,MySQL根据通常的 MySQL 类型转换规则隐式将其转换为声明的类型。见第14.3节,“表达式求值中的类型转换”

如果数据类型指定不包含明确的DEFAULT值,MySQL按以下方式确定默认值:

如果列可以取NULL值,则将列定义为明确的DEFAULT NULL子句。

如果列不能取NULL值,MySQL将列定义为无明确的DEFAULT子句。

对于无明确DEFAULT子句的NOT NULL列,如果INSERTREPLACE语句不包含该列值,或者UPDATE语句将该列设置为NULL,MySQL根据生效的 SQL 模式处理该列:

  • 如果严格 SQL 模式启用,事务表中发生错误,语句回滚;非事务表中发生错误,但如果是多行语句的第二行或后续行,则前面的行被插入。

  • 如果不启用严格模式,MySQL 将该列设置为该列数据类型的隐式默认值。

假设表 t 定义如下:

CREATE TABLE t (i INT NOT NULL);

在严格模式下,每个以下语句都产生错误,不插入任何行;不使用严格模式时,只有第三个语句产生错误,前两个语句隐式默认值被插入,但第三个失败,因为 DEFAULT(i) 无法生成值:

INSERT INTO t VALUES();
INSERT INTO t VALUES(DEFAULT);
INSERT INTO t VALUES(DEFAULT(i));

请参见第7.1.11节,“服务器 SQL 模式”.

对于给定的表,SHOW CREATE TABLE 语句显示哪些列具有明确的 DEFAULT 子句。

隐式默认值定义如下: