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

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 拾遗:系列文章

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/340908.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL即服务

自2007年以来,我一直在考虑这一点,大约在Amazon 推出 S3时。 我什至尝试实现了几次,但是在设计阶段之后就失败了。 我听说过一家初创公司,也曾尝试这样做,但也失败了 。 我仍然不确定是否可以这样做,但是它…

c++ vector 一部分_《JACS》:在富电子C-H键位点上实现光控活性聚合

可逆加成-断裂链转移(RAFT)自由基活性聚合是一种调控聚合物结构组成、分子量和分布的重要聚合方法,其中,光诱导电子/能量转移(PET)的RAFT聚合反应是一种更精确的调控手段,因而经常被用于设计具有复杂3D分子结构的聚合物。然而常规的PET-RAFT法…

phpmyadmin忘记mysql密码_忘记phpmyadmin密码怎么重置

忘记phpmyadmin密码怎么重置,新密码,教程,相关文章,重新启动,跳过忘记phpmyadmin密码怎么重置易采站长站,站长之家为您整理了忘记phpmyadmin密码怎么重置的相关内容。1、停止mysql服务:/etc/init.d/mysql stop2、跳过验证启动MySQL/usr/local/mysql/bin/…

java中避免空指针_在Java中避免空检查

java中避免空指针对于Java开发人员(从初级到专家)最糟糕的噩梦之一是空对象引用检查。 我很确定您已经看过几次这样的代码: public void addAddressToCustomer(Customer customer, Address newAddress){if ( cutomer null || newAddress n…

纵横免root框架打不开应用怎么办_很好用的软件多开神奇安卓欧皇十框架!!!...

欧皇十框架这是一款兼容安卓10的应用框架,轻松实现应用多开,可以完美免ROOT运行GG修改器,专为和平精英游戏设计,软件体积小,运行稳定。修改说明:1.支持更多应用游戏的多开、双开,使用更稳定、快…

用java和mysql开发网站怎么实现_如何用java开发一个网站?

java语言和类库:java语言是支持整个java技术的底层基础,java类库是随java语言Java 运行系统:主要指java虚拟机,负责将java与平台无关的中间代码翻译成本机的Java applet :Java applet 是用java语言编写的小应用程序,通…

Elasticsearch SQL

Elasticsearch引擎 Elasticsearch是当今许多生产部署中使用最广泛的搜索引擎之一。 它基于Lucene搜索库,它提供的主要功能之一是在Lucene之上的基于JSON的查询DSL,它提供了一种易于使用的机制来与搜索引擎进行交互。 但是,查询DSL非常特定于E…

电脑无internet访问_电脑中的代理服务器怎么设置 代理服务器设置方法 - 操作系统...

如何设置电脑中的代理服务器?对于代理服务器,可能大家对其并不是非常了解,其实代理服务器作为一种特殊的网络服务,可以代理网络用户去获取网络信息,提高浏览速度与效率,而且还可以突破自身IP的访问限制,访…

mysql先进后出_栈、队列中“先进先出”,“后进先出”的含义

展开全部先进先出(62616964757a686964616fe58685e5aeb931333433653339FIFO,first-in,first-out)为处理从队列或堆栈发出的程序工作要求的一种方法,它使最早的要求被最先处理。后进先出,从栈中取出数据项的顺序与将它们插入栈的顺序…

平台框架_从框架到平台

平台框架当我在十年前以Java开发人员的身份开始职业生涯时,该行业正经历着革命性的变化。 2003年发布的Spring框架Swift流行,并成为庞大的J2EE平台的严重挑战者。 经过过渡时间后,我很快发现自己赞成使用Spring框架而不是J2EE平台&#xff0c…

敲代码时如何快速移动光标_如何用 Linux 技巧大大提高工作效率?

前言Linux中的一些小技巧可以大大提高你的工作效率,本文就细数那些提高效率或者简单却有效的Linux技巧。命令编辑及光标移动这里有很多快捷键可以帮我们修正自己的命令。接下来使用光标二字代替光标的位置。删除从开头到光标处的命令文本ctrl u,例如&am…

Java 13:文本块

Java 13已交付了期待已久的多行字符串或Text Blocks 。 您不再需要连接跨越多行的字符串或转义特殊字符,这确实提高了代码的可读性。 文本块是一种预览语言功能 ,这意味着必须使用--enable-preview标志在Java编译器和运行时中明确启用它们。 这是一个文…

java 异常练习题_java入门异常处理练习题问题

tppe大概方式:1、判断用户输入的类型是否正确,不正确捕获异常,把他包装成我自己定义的异常2、判断用户输入的数是多少2.1、如果是1,则打印“输入图书名称”,用户输入,定义一个Book类型的数组,然…

windows副本不是正版怎么办_盗版系统总是崩溃?别着急,让我来告诉你正版系统怎么下载...

电脑系统崩溃了怎么办?相信很多小伙伴都会选择重装系统,奈何自己又不会,只能搬到修电脑的地方,最后发现安装的还是盗版系统,不能登录微软账号不说,还会被捆绑安装一堆流氓软件,那么,…

java线程有几种状态_java线程的几种状态

java线程的几种状态导语:线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。下面是Java线程的介绍,欢迎参考!新建:new一个Thread对象或者其子类对象就是创建一个线程&#xff0…

sudo spctl --master-disable_量大从优批发--阳离子聚丙烯酰胺--用于生活污水、

量大从优批发--阳离子聚丙烯酰胺--用于生活污水、wkkk量大从优批发--阳离子聚丙烯酰胺--用于生活污水、怎么来辨别聚丙烯酰胺到底是什么型号的呢?下面来介绍型号辨别的消防法。聚丙烯酰胺我们都知道聚丙烯酰基是昂贵的阳离子,其次是非离子聚丙烯酰胺&…

java 框架 例子_如何设计Java框架? –一个简单的例子

通过优锐课核心java学习笔记中,我们可以看到,码了很多专业的相关知识, 分享给大家参考学习。你可能对框架如何工作感到好奇? 这里将通过一个简单的框架示例来说明框架的思想。框架目标首先,为什么我们需要一个除普通库…

jboss eap_HawtIO在JBoss EAP上(第二部分)

jboss eap我刚刚发布了一篇关于在JBoss Wildfly 8.1上运行HawtIO的条目 。 从那篇文章中,您将了解HawtIO的出色表现 ,以及它必须具备的所有 出色 插件,才能从单个仪表板管理基于JVM的技术……好吧…… hawt ……。 但是,出于上一…

alter id order by_声卡id查找表

强烈建议收藏这个表格真的很方便,强烈建议大家收藏,尤其是那些喜欢折腾的人!因为有时候会特别需要它声卡ID表芯片型号仿冒ID创作的CA01320x100918仿冒ID值 0,1,2,3,4,5,6,9,10,11,12Cirrus Logic公司CS42100x100101仿冒ID值 13Cirrus Logic公…

java bean id_在 JSP中使用JavaBean的标签是 ,其中 id的用途是 __________________学小易找答案...

【多选题】Flash渐变动画分为()。P22【单选题】关于 JavaBean,下列的叙述哪一项是不正确的?( )【填空题】用户在实际 Web应用开发中,编写Bean除了要使用 ___________________ 引入 Java的标准类。【单选题】Its very foolish _____ it.【填空题】在 Web服务器端使用JavaBean,将…