MySQL sql_mode的使用詳解
前言
相信看過上一篇文章《MySQL案例:一個數據丟失慘案》的童鞋,都應該意識到,sql_mode是一個非常關鍵的配置,接下來就帶來該配置項的詳細解析。
sql_mode詳解
sql_mode,會直接影響SQL語法支持和數據校驗,它包含非常多的選項,其中5.7版本的默認值是
“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”
,一般不建議進行修改。
最重要的選項
sql_mode最重要的選項,包括以下3個:
(1)ANSI:該選項決定SQL語法支持,設置為ANSI,會更加遵守標準SQL語法。
(2)STRICT_TRANS_TABLES:該選項決定數據校驗;對於事務性存儲引擎,當出現非法值時,該事務會失敗並回滾;對於非事務性存儲引擎,如果非法值出現在第一行,那麼該事務會失敗,如果非法值出現在中間,那麼會調整非法值,並拋出告警。
(3)TRADITIONAL:該選項決定與傳統關系型數據庫表現一致;對於一些非正常操作,直接報錯失敗而不是告警提示。
全部選項
sql_mode還包括以下選項:
(4)ALLOW_INVALID_DATES:該選項決定不進行嚴格的日期校驗;它隻校驗月份范圍是否為1-12、日期范圍是否為1-31,不校驗具體日期是否有效,比如2020-04-31這個非法日期是允許的。
(5)ANSI_QUOTES:該選項決定引用字符;它允許雙引號”作為引用字符,和反引號`一樣。
(6)ERROR_FOR_DIVISION_BY_ZERO:該選項決定被零整除的返回值;如果不啟用,那麼被零整除的返回值為null且不告警;如果啟用但在非嚴格模式下,那麼被零整除的返回值為null且產生告警;如果啟用且在嚴格模式下,那麼被零整除會直接報錯。
(7)HIGH_NOT_PRECEDENCE:該選項決定not操作的優先級;啟用後,NOT a BETWEEN b AND c被解析為NOT (a BETWEEN b AND c);在一些舊版本中,NOT a BETWEEN b AND c被解析為(NOT a) BETWEEN b AND c。
(8)IGNORE_SPACE:該選項決定忽略函數名和括號之間的空格;啟用後,比如count (*)也不會報錯。
(9)NO_AUTO_CREATE_USER:該選項決定grant語句不會自動創建用戶;已過時,grant語句也不會創建用戶。
(10)NO_AUTO_VALUE_ON_ZERO:該選項決定自增列的生成;一般來說,向自增列插入0或null,系統會自動生成下一個自增值插入;啟用後,向自增列插入0會保留原值0,插入null才會自動生成下一個自增值插入
(11)NO_BACKSLASH_ESCAPES:該選項決定反斜杠\的作用;啟用後,反斜杠\不再作為轉義字符,而是用作普通字符。
(12)NO_DIR_IN_CREATE:該選項決定忽略創建表時,所有的INDEX DIRECTORY和DATA DIRECTORY指令;該選項隻在從庫生效。
(13)NO_ENGINE_SUBSTITUTION:該選項決定創建表時,如果指定一個不存在/不支持的存儲引擎,那麼會自動轉換為默認存儲引擎。
(14)NO_FIELD_OPTIONS:已過時。
(15)NO_KEY_OPTIONS:已過時。
(16)NO_TABLE_OPTIONS:已過時。
(17)NO_UNSIGNED_SUBTRACTION:一般情況下,整數之間的減法(其中一個為無符號),結果為無符號,如果結果為負數則報錯;啟用該選項後,負數則可以正常處理。
(18)NO_ZERO_DATE:該選項決定‘0000-00-00’是否可以插入;如果不啟用,那麼‘0000-00-00’可以插入且不告警;如果啟用但在非嚴格模式下,那麼‘0000-00-00’可以插入但會產生告警;如果啟用且在非嚴格模式下,那麼‘0000-00-00’不能插入會直接報錯。
(19)NO_ZERO_IN_DATE:該選項決定月份和日期是否可以為00;如果不啟用,那麼月份和日期可以為00且不告警;如果啟用但在非嚴格模式下,那麼月份和日期可以為00但會產生告警;如果啟用且在非嚴格模式下,那麼月份和日期不能為00會直接報錯。
(20)ONLY_FULL_GROUP_BY:該選項決定select/having/order by後面的非聚合字段,必須出現在group by字句中。
(21)PAD_CHAR_TO_FULL_LENGTH:一般情況下,查詢char類型的字段,後面的空洞數據會被裁剪;啟用該選項後,查詢char類型的字段,後面的空洞數據不會被裁剪。
(22)PIPES_AS_CONCAT:該選項決定將||符號當作字符串的連接操作符,而不是當作OR同義詞。
(23)REAL_AS_FLOAT:該選項決定將REAL當作FLOAT同義詞,而不是DOUBLE同義詞。
(24)STRICT_ALL_TABLES:該選項決定數據校驗;對於事務性存儲引擎,當出現非法值時,該事務會失敗並回滾;對於非事務性存儲引擎,如果非法值出現在第一行,那麼該事務會失敗,如果非法值出現在中間,那麼前面操作會成功、後面操作會直接報錯,出現事務部分成功部分失敗的情況。
總結
通過上面的學習,相信大傢對sql_mode各選項,都有較為詳細的瞭解;關於sql_mode如何設置,個人建議如下:
(1)對於5.5/5.6版本,sql_mode建議參照5.7默認值進行設置;
(2)對於5.7版本,sql_mode保持默認值即可;
(3)對於8.0版本,sql_mode也保持默認值即可。
sql_mode的設置,可以讓MySQL非常靈活地運行在各種不同模式下,但與此同時也帶來各種各樣的風險;在MySQL廣泛應用於各類重要系統的情況下,建議是要對sql_mode進行嚴格審核設置,同時對開發代碼進行規范化管理;其實這一點,也可以從官方默認值看出來,隨著MySQL版本的迭代,sql_mode的設置也是越來越嚴格。
以上就是MySQL sql_mode的使用詳解的詳細內容,更多關於MySQL sql_mode的使用的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- MySQL 5.7之關於SQL_MODE的設置
- MySQL運行報錯:“Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggre”解決方法
- sql模式設置引起的問題解決辦法
- MySQL sql_mode修改不生效的原因及解決
- 高版本Mysql使用group by分組報錯的解決方案