MySQL 如何處理隱式默認(rèn)值
有同學(xué)說遇到了主從不一致的問題。
大概情況是,從庫是用mysqldump導(dǎo)出導(dǎo)入數(shù)據(jù)的方式創(chuàng)建的。創(chuàng)建成功后,在用mysqldump驗證主從的表結(jié)構(gòu)是否一致的時候,發(fā)現(xiàn)有些表定義不一致:
從他的比較結(jié)果可以看到,在從庫端,有三個列的定義中被加入了“default null”。
懷疑環(huán)境被人人為修改過,但是最終確認(rèn)環(huán)境沒有被動過。然后又做了一邊測試,使用mysqldump導(dǎo)出數(shù)據(jù),使用source將數(shù)據(jù)導(dǎo)入從庫后,發(fā)現(xiàn)還是有這個現(xiàn)象,問是不是source命令有bug!
其實,這個跟MySQL內(nèi)部如何處理隱式默認(rèn)值有關(guān)。如果數(shù)據(jù)類型沒有包含顯式的default值,MySQL會按照如下的規(guī)則確定默認(rèn)值:·如果該列可以采用NULL值作為值,該列在定義的時候會被加上一個顯式的default null子句·如果該列不可以采用NULL值作為值,該列在定時候就不會加上一個顯式的default子句
對于將數(shù)據(jù)輸入沒有顯式DEFAULT子句的NOT NULL列的情況,如果INSERT或REPLACE語句不包含該列的值,或者UPDATE語句將該列設(shè)置為NULL,屆時則MySQL將根據(jù)有效的SQL Mode處理該列:·如果啟用了嚴(yán)格的SQL模式(strict SQL mode),則事務(wù)表將發(fā)生錯誤,并且該語句將回滾。對于非事務(wù)表,會發(fā)生錯誤,但是如果此錯誤發(fā)生在多行語句的第二行或后續(xù)行中,則該錯誤之前的所有行均已插入。·如果未啟用嚴(yán)格模式,則MySQL將列設(shè)置為列數(shù)據(jù)類型的隱式默認(rèn)值。
假設(shè)表t定義如下:
mysql> create table t(i int not null);
這里,i沒有顯式的默認(rèn)值。在嚴(yán)格的sql mode下,下面的語句都會產(chǎn)生錯誤,插入失敗。
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 valuemysql> INSERT INTO t VALUES(DEFAULT);ERROR 1364 (HY000): Field ’i’ doesn’t have a default valuemysql> INSERT INTO t VALUES(DEFAULT(i));ERROR 1364 (HY000): Field ’i’ doesn’t have a default valuemysql>
在非嚴(yán)格的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 valuemysql> select * from t;+---+| i |+---+| 0 || 0 |+---+2 rows in set (0.01 sec) mysql>
對于給定的表,SHOW CREATE TABLE語句顯示哪些列具有顯式的DEFAULT子句。對于隱式的默認(rèn)值定義如下:·對于numeric類型,默認(rèn)值為0,但對于用AUTO_INCREMENT屬性聲明的整數(shù)或浮點類型,默認(rèn)值為序列中的下一個值。·對于除TIMESTAMP以外的date和time類型,默認(rèn)值為該類型的'零'值。如果啟用了explicit_defaults_for_timestamp系統(tǒng)變量,對于TIMESTAMP也是如此。否則,對于表中的第一個TIMESTAMP列,默認(rèn)值為當(dāng)前日期和時間。·對于ENUM以外的其他字符串類型,默認(rèn)值為空字符串。對于ENUM,默認(rèn)值為第一個枚舉值。
mysql> create table t1(id int,name varchar(20));Query OK, 0 rows affected (0.04 sec) mysql> show create table t1G*************************** 1. row *************************** Table: t1Create Table: CREATE TABLE `t1` ( `id` int(11) DEFAULT NULL, `name` varchar(20) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf8mb41 row in set (0.00 sec) mysql>
以上就是MySQL 如何處理隱式默認(rèn)值的詳細(xì)內(nèi)容,更多關(guān)于MySQL 隱式默認(rèn)值的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!
相關(guān)文章:
1. MYSQL(電話號碼,身份證)數(shù)據(jù)脫敏的實現(xiàn)2. Windows系統(tǒng)徹底卸載SQL Server通用方法(推薦!)3. SQL Server2022安裝圖文教程(最新推薦)4. MySQL 性能優(yōu)化,讓數(shù)據(jù)庫跑的更快5. Mysql中的日期時間函數(shù)小結(jié)6. 根據(jù)IP跳轉(zhuǎn)到用戶所在城市的實現(xiàn)步驟7. MySQL兩千萬數(shù)據(jù)優(yōu)化&遷移8. Sql在多張表中檢索數(shù)據(jù)的方法詳解9. debian10 mariadb安裝過程詳解10. Navicat for MySQL的使用教程詳解
