文章详情

短信预约信息系统项目管理师 报名、考试、查分时间动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

MySQL 如何处理隐式默认值

2022-05-31 09:18

关注

有同学说遇到了主从不一致的问题。

大概情况是,从库是用mysqldump导出导入数据的方式创建的。创建成功后,在用mysqldump验证主从的表结构是否一致的时候,发现有些表定义不一致:

从他的比较结果可以看到,在从库端,有三个列的定义中被加入了“default null”。

怀疑环境被人人为修改过,但是最终确认环境没有被动过。然后又做了一边测试,使用mysqldump导出数据,使用source将数据导入从库后,发现还是有这个现象,问是不是source命令有bug!

其实,这个跟MySQL内部如何处理隐式默认值有关。

如果数据类型没有包含显式的default值,MySQL会按照如下的规则确定默认值:
·如果该列可以采用NULL值作为值,该列在定义的时候会被加上一个显式的default null子句
·如果该列不可以采用NULL值作为值,该列在定时候就不会加上一个显式的default子句

对于将数据输入没有显式DEFAULT子句的NOT NULL列的情况,如果INSERT或REPLACE语句不包含该列的值,或者UPDATE语句将该列设置为NULL,届时则MySQL将根据有效的SQL Mode处理该列:
·如果启用了严格的SQL模式(strict SQL mode),则事务表将发生错误,并且该语句将回滚。对于非事务表,会发生错误,但是如果此错误发生在多行语句的第二行或后续行中,则该错误之前的所有行均已插入。
·如果未启用严格模式,则MySQL将列设置为列数据类型的隐式默认值。

假设表t定义如下:


mysql> create table t(i int not null);

这里,i没有显式的默认值。
在严格的sql mode下,下面的语句都会产生错误,插入失败。


mysql> show variables like '%sql_mode%';
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| Variable_name | Value                                                                                                                                     |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
| sql_mode      | ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+---------------+-------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
 
mysql> INSERT INTO t VALUES();
ERROR 1364 (HY000): Field 'i' doesn't have a default value
mysql> INSERT INTO t VALUES(DEFAULT);
ERROR 1364 (HY000): Field 'i' doesn't have a default value
mysql> INSERT INTO t VALUES(DEFAULT(i));
ERROR 1364 (HY000): Field 'i' doesn't have a default value
mysql>

在非严格的sql mode下:


mysql> SET @@sql_mode='';
Query OK, 0 rows affected, 1 warning (0.00 sec)
 
mysql> show variables like '%sql_mode%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| sql_mode      |       |
+---------------+-------+
1 row in set (0.00 sec)
 
mysql> INSERT INTO t VALUES();
Query OK, 1 row affected, 1 warning (0.00 sec)
 
mysql> INSERT INTO t VALUES(DEFAULT);
Query OK, 1 row affected, 1 warning (0.01 sec)
 
mysql> INSERT INTO t VALUES(DEFAULT(i));
ERROR 1364 (HY000): Field 'i' doesn't have a default value
mysql> select * from t;
+---+
| i |
+---+
| 0 |
| 0 |
+---+
2 rows in set (0.01 sec)
 
mysql>

对于给定的表,SHOW CREATE TABLE语句显示哪些列具有显式的DEFAULT子句。对于隐式的默认值定义如下:
·对于numeric类型,默认值为0,但对于用AUTO_INCREMENT属性声明的整数或浮点类型,默认值为序列中的下一个值。
·对于除TIMESTAMP以外的date和time类型,默认值为该类型的"零"值。如果启用了explicit_defaults_for_timestamp系统变量,对于TIMESTAMP也是如此。否则,对于表中的第一个TIMESTAMP列,默认值为当前日期和时间。
·对于ENUM以外的其他字符串类型,默认值为空字符串。对于ENUM,默认值为第一个枚举值。


mysql> create table t1(id int,name varchar(20));
Query OK, 0 rows affected (0.04 sec)
 
mysql> show create table t1\G
*************************** 1. row ***************************
       Table: t1
Create Table: CREATE TABLE `t1` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
1 row in set (0.00 sec)
 
mysql>

以上就是MySQL 如何处理隐式默认值的详细内容,更多关于MySQL 隐式默认值的资料请关注自学编程网其它相关文章!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-数据库
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯