MySQL 中,所有的数据类型,都可以显式或隐式的拥有默认值。

我们可以使用 DEFAULT 约束显式的为列指定一个默认值。比如

CREATE TABLE t1 (

i INT DEFAULT -1,

c VARCHAR(10) DEFAULT '',

price DOUBLE(16,2) DEFAULT 0.00

);

在上面这条语句中,我们为 int 类型的 i 列指定了默认值 -1 ,为 varchar 类型的 c 列指定了默认值 '' ,为 double 类型的 price 列指定了默认值 0.00。也就是说,当我们插入数据的时候,并不需要完整的为每一列指定值。如果没有指定值,那么 MySQL 就会使用默认值填充。

但是,DEFAULT 约束有有一个特例,就是 SERIAL DEFAULT VALUE。等于类型为整形的列,它的作用相当于 NOT NULL AUTO_INCREMENT UNIQUE。

其实这不怪 DEFAULT ,是 SERIAL 的锅。

但是,default 并不是没有 bug,显式 DEFAULT 约束处理的某些方面依赖于版本。

MySQL 8.0.13 中处理显式默认值

DEFAULT 约束中指定的默认值可以是文字常量或表达式。

如果使用表达式作为默认值,则需要表达式默认值括在括号内 () ,以将它们与文字常量默认值区分开来。

例如

CREATE TABLE t1 (

-- 常量默认值

i INT DEFAULT 0,

c VARCHAR(10) DEFAULT '',

-- 表达式默认值

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())

);

但是,这有一个例外。这个例外就是: TIMESTAMP 和 DATETIME 列。

对于 TIMESTAMP 和 DATETIME 列,我们可以将 CURRENT_TIMESTAMP 函数指定为默认值,而需要添加括号。

CREATE TABLE t1 (

-- 常量默认值

c TIMESTAMP DEFAULT CURRENT_TIMESTAMP,

u DATETIME DEFAULT CURRENT_TIMESTAMP,

);

而对于 BLOB,TEXT,GEOMETRY和 JSON 数据类型,只有在将值写为表达式时,才能分配默认值,即使表达式值是文字也是如此。

例如,下面这种写法是允许的,也就是使用文字字面量表达式

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

但下面这种写法则是不允许的,因为它是一个字面量而不是一个表达式

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

表达式默认值必须遵守以下规则。如果表达式包含不允许的构造,则会发生错误

允许使用文字,内置函数(确定性和非确定性)和运算符

不允许使用子查询,参数,变量,存储函数和用户定义的函数

表达式默认值不能依赖于具有 AUTO_INCREMENT 属性的列。

某一列的表达式默认值可以引用另外一张表中的列,但是对生成的列或具有表达式默认值的列的引用必须是对于在表定义中较早出现的列。也就是说,表达式默认值不能包含对生成的列或具有表达式默认值的列的前向引用。翻译成白话文就是,引用的列必须已经存在。

排序 ( ordering ) 约束也适用于使用 ALTER TABLE 重新排序表列。如果结果表的表达式默认值包含对具有表达式默认值的生成列或列的前向引用,则该语句将失败

注意: 如果表达式默认值的任何组件取决于 SQL 模式,则表的不同用法可能会出现不同的结果,除非在所有使用过程中 SQL 模式都相同

对于语句 CREATE TABLE ... LIKE 和 CREATE TABLE ... SELECT ,目标表保留原始表中的表达式默认值。

如果表达式默认值引用非确定性函数,则导致表达式计算的任何语句对于基于语句的复制都是不安全的。包括 INSERT,UPDATE 和 ALTER TABLE 等语句

插入新行时,可以通过省略列名或将列指定为 DEFAULT 来插入具有表达式 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 8.0.13 之前的版本中处理显式默认值

MySQL 8.0.13 之前的版本,DEFAULT 约束中指定的默认值必须是文字常量,而不能是一个函数或表达式。

但有一个例外,这个例外就是: TIMESTAMP 和 DATETIME 列。

这意味着,我们不能将 date 列的默认值设置为函数的值,例如 NOW() 或 CURRENT_DATE 。

而对于 BLOB , TEXT ,GEOMETRY 和 JSON 数据类型,根本就不允许分配默认值。

同样的,如果默认值的计算结果与声明的列类型不同,则根据通用的 MySQL 类型转换规则对声明的类型进行隐式强制。

处理隐式默认值

如果在定义表结构时不使用 DEFAULT 约束为列显式定义默认值,MySQL 将自己决定如何设置默认值。

如果列可以将 NULL 作为值,则会使用显式的 DEFAULT NULL 子句定义该列。其实不用显式,因为它就是默认的定义。

如果列不能将 NULL 作为值,则 MySQL 会定义没有显式 DEFAULT 子句的列。也就是并不会添加 DEFAULT 约束。

但这两条规则有一个例外,如果列被定义为 PRIMARY KEY 的一部分但未显式设置为 NOT NULL,则 MySQL 将其创建为 NOT NULL 列( 因为PRIMARY KEY 列必须为 NOT NULL )。

对于没有显式 DEFAULT 约束的 NOT NULL 列的数据输入,如果 INSERT 或 REPLACE 语句不包含该列的值,或者 UPDATE 语句将列设置为 NULL ,MySQL 会根据当时生效的 SQL 模式处理列:

如果启用了严格的 SQL 模式,则事务表会发生错误,并且会回滚 SQL 语句。对于非事务性表,会发生错误,但如果多行语句的第二行或后续行发生这种情况,则前面的行会正常插入。

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

对于这段叙述,总觉得很拗口,好不,我们举个例子来说明下,假设表 t 定义如下

CREATE TABLE t (i INT NOT NULL);

上面这个表定义语句中,我们并没有为 i 字段显式的定义默认值,因此在严格模式下,以下每个语句都会产生错误,并且不会插入任何行。

INSERT INTO t VALUES();

INSERT INTO t VALUES(DEFAULT);

INSERT INTO t VALUES(DEFAULT(i));

不使用严格模式时,只有第三个语句产生错误,因为前两个语句插入了隐式默认值,但第三个语句失败,因为 DEFAULT(i) 无法生成值。

对于给定的表,我们可以使用 SHOW CREATE TABLE 语句显示哪些列具有显式 DEFAULT 约束。

而对于隐式默认值,则定义如下

对于数字类型,默认值为 0,但对于使用 AUTO_INCREMENT 属性声明的整数或浮点类型,默认值是序列中的下一个值。

对于 TIMESTAMP 以外的日期和时间类型,默认值为该类型的相应 「 零 」 值。如果启用了 explicit_defaults_for_timestamp 系统变量,那么 TIMESTAMP 类型的列的默认值也是 「 零 」 值。否则,对于表中的第一个 TIMESTAMP 列,默认值为当前日期和时间。

对于 ENUM 以外的字符串类型,默认值为空字符串 ( "")。对于 ENUM 类型,默认值是第一个枚举值

干货推荐

附录:MySQL 拾遗:系列文章

mysql+默认值+default_十六、MySQL 中数据类型的默认值 - default 约束-搜云库相关推荐

  1. 我的MYSQL学习心得(十六) 优化

    原文:我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(十六) 优化 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看 ...

  2. CCIE-LAB-第十六篇-NAT+OSPF下发默认路由+校验配置(模块一结束篇章)

    CCIE-LAB-第十六篇-NAT+OSPF下发默认路由+校验配置(模块一结束篇章) 实际中,思科只会给你5个小时去做下面的全部配置 这个是CCIE-LAB的拓扑图 问题 翻译: 根据这些要求1为FA ...

  3. linux 正点原子ov5640_【正点原子FPGA连载】第二十六章基于OV5640的二值化实验-摘自【正点原子】领航者 ZYNQ 之嵌入式开发指南 (amobbs.com 阿莫电子论坛)...

    本帖最后由 正点原子 于 2020-10-26 16:21 编辑 QQ群头像.png (1.78 KB) 2020-10-24 10:50 上传5)关注正点原子公众号,获取最新资料 100846rel ...

  4. MySQL开发技巧 第二禅(子查询中匹配两个值、解决同属性多值过滤的问题、计算累进税的问题)

    一.如何在子查询中匹配两个值 mysql子查询的使用场景及其好处 1.什么是子查询?             当一个查询是另一个查询的条件时,称之为子查询(可以在curd中) 2.常见的子查询使用场景 ...

  5. 燕十八 mysql 复习_燕十八 Mysql 笔记 68 课

    68 建表过程与字符类型的意义 目的:要学会建表 知识点:列类型 怎么建表? 以在 A4 纸上建表为例,表头写完就算表建好了,后面的是插入数据,建表的过程其实就是一个声明字段的过程 学号 姓名 家乡 ...

  6. mysql 性能分析_十大MySQL性能分析工具汇总!专治MySQL性能瓶颈

    前言 MySQL 数据库最常见的两个瓶颈是CPU和I/O的瓶颈.CPU在饱和的时候一般发生在数据装入内存或从磁盘上读取数据时候,磁盘I/O瓶颈发生在装入数据远大于内存容量的时候. MySQL数据库性能 ...

  7. 机器学习基础(三十六)—— 非规整数据(值缺失、异常值)的处理

    (1)非规整 (2)值缺失 (3)异常值(outlier) 一般来说,现实中的数据会存在信息不完整.数据点缺失和异常值的情况,理想情况下,我们会去尝试修复非规整数据,但很多数据集都源于一些难以重现(不 ...

  8. Java 基础系列(十六) --- Java中模板引擎的使用

    模板引擎 1 关于动态页面的渲染 2 非模板引擎的弊端 3 模板引擎 3.1 什么是模板引擎? 3.2 Thymeleaf 语法 3.3 模板引擎的使用 4 总结 1 关于动态页面的渲染   渲染就是 ...

  9. Java中数据类型的取值范围

    整数数据类型的取值范围 我们都知道计算机的底层是二进制,也知道不同的整数类型存储值的范围不同,可这些数值在计算机底层是怎样存储的呢?数值范围又是怎么计算出来的呢? 下面以java来进行举例: byte ...

最新文章

  1. select,InnoDB为啥会阻塞insert?
  2. 深度学习搞CV?图像数据不足咋办?看这里!
  3. Spring Boot中使用Swagger CodeGen生成REST client
  4. java 旋转图片_Java实现图片翻转以及任意角度旋转
  5. matlab 图像分割
  6. jquery连续滚动
  7. 剑指Offer--二维数组中的查找
  8. paip.终端服务器超出了最大允许连接数的解决
  9. vue 微信分享至朋友圈分享至朋友代码封装
  10. 荣耀7升级android8,华为+荣耀7款老爷机齐升安卓8.0:最近两年全覆盖
  11. python大数据就业方向_大数据专业未来的就业方向有哪些?[黑马程序员]
  12. 推荐 9 个免费图片网站,我的存货都在这了
  13. Python小游戏:BMI指数的计算
  14. 「AI芯片公司」比特大陆的路线图上,除了四款TPU还有在这三个产业落地的野心
  15. java用什么测试工具_10款常用的JAVA测试工具
  16. 初学者需要了解Linux这么多
  17. 超声波传感器四大检测方法详解
  18. Mac OS 下三种修改Hosts文件的方法
  19. 企业邮箱账号注册格式怎么写?
  20. java做flv直播服务器_一种RTMP直播流到HTTPFLV直播流实时转换系统及其工作方法与流程...

热门文章

  1. 类加载器 jboss_JBoss AS 7类加载说明
  2. 看一下即将发布的JSF 2.3 Push支持
  3. Spring MVC:Trgger手动验证表单对象
  4. saxparser_使用SaxParser和完整代码进行XML解析
  5. Spark 101:它是什么,它做什么以及为什么起作用
  6. Web应用程序体系结构– Spring MVC – AngularJs堆栈
  7. ClassNotFoundException:是否减慢了您的JVM?
  8. 用Java递增Map值的最有效方法–仅搜索一次键
  9. Java Comparable接口的陷阱
  10. Spring:设置日志依赖项