欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

MySQL 如何处理隐式默认值

程序员文章站 2022-09-02 10:07:03
有同学说遇到了主从不一致的问题。大概情况是,从库是用mysqldump导出导入数据的方式创建的。创建成功后,在用mysqldump验证主从的表结构是否一致的时候,发现有些表定义不一致:从他的比较结果可...

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

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

MySQL 如何处理隐式默认值

从他的比较结果可以看到,在从库端,有三个列的定义中被加入了“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 隐式默认值的资料请关注其它相关文章!