國產數據庫兼容過程中涉及的MySQL非嚴格模式
在國產數據庫兼容適配過程中,經常遇到因源數據庫是MySQL,遷移至其他國產數據庫后,因MySQL端兼容模式有非嚴格模式,導致適配過程過程中需要做調整。那么,MySQL主要的非嚴格模式小結如下:
1、非嚴格模式參數
MySQL的非嚴格模式指的是在MySQL配置中禁用嚴格模式(Strict Mode)的情況下執行的SQL。在非嚴格模式下,MySQL會對某些數據插入、更新和比較操作執行隱式轉換,從而在一些情況下允許執行一些寬松的操作,而不拋出錯誤或警告。
涉及的主要參數說明如下:
a) STRICT_TRANS_TABLES:在插入或更新數據時,禁止自動轉換類型,確保所有數據都符合表定義的數據類型范圍。如果值無法轉換為合法的數據類型,則拋出錯誤。
b) STRICT_ALL_TABLES:對所有表都啟用STRICT_TRANS_TABLES模式,確保數據插入或更新時嚴格符合表定義的數據類型。
c) NO_ZERO_IN_DATE:禁止在日期中使用零值,例如'0000-00-00',在嚴格模式下會被視為非法日期。
d) NO_ZERO_DATE:禁止使用零值表示日期的部分,例如'2000-00-00',在嚴格模式下會被視為非法日期。
e) ERROR_FOR_DIVISION_BY_ZERO:當除數為零時,拋出錯誤而不是返回NULL。
f) ANSI_QUOTES:啟用ANSI_QUOTES模式,要求使用雙引號來引用字符串,而不是MySQL默認的單引號。
g) NO_AUTO_CREATE_USER:禁止在GRANT語句中自動創建新用戶。
h) NO_ENGINE_SUBSTITUTION:如果指定的存儲引擎不可用,不允許MySQL使用默認的存儲引擎替代。
2、簡單舉例
以下是一些非嚴格模式下可能出現的案例情況:
非嚴格的日期和時間插入:在非嚴格模式下,MySQL允許插入不符合日期和時間格式的值,會自動進行轉換或舍入
eg: 不合法的日期值'0000-00-00'等
非嚴格的字符串插入:在非嚴格模式下,MySQL允許插入過長的字符串,會自動截斷超過字段長度的部分 (建議已開啟此類嚴格模式)
eg: varchar(2) 類型的字段,插入ABC可以成功,插入結果為AB
非嚴格的數值插入:在非嚴格模式下,MySQL允許插入超出字段范圍的數值,會自動進行范圍調整(建議已開啟此類嚴格模式)
eg: TINYINT(默認最大127) 可以插入150,且插入后的值自動截斷為 127
非嚴格的零值插入:在非嚴格模式下,MySQL允許插入字符串類型的值到數值類型字段,會將非數值字符串轉換為0 (建議已開啟此類嚴格模式)
eg: 例如可以將字符串'123' 插入int類型,結果是123;將'abc'插入int,結果是0
非嚴格的分組查詢:在非嚴格模式下,MySQL允許在GROUP BY查詢中選擇非聚合列,這可能導致不確定的結果
eg: SELECT a,b,COUNT(*) FROM tb GROUP BY a
非嚴格的NULL值比較:在非嚴格模式下,MySQL允許使用普通比較運算符(如=、<、>等)與NULL值進行比較,這可能導致不確定的結果 (建議已開啟此類嚴格模式)
eg: column_name =NULL 或者 column_name <> NULL
非嚴格的外鍵約束:在非嚴格模式下,MySQL對外鍵約束的檢查較為寬松,可能會允許插入或更新關聯字段中不存在的值。(建議已開啟此類嚴格模式)
eg: tb表外鍵字段指向ta表的主鍵,如果tb表的外鍵字段插入的內容不存在于a表中時也可以寫入成功
非嚴格的除數為0校驗:在非嚴格模式下,MySQL允許除數為0
eg: 10/0 ,結果為null
非嚴格的字符串引號標識:在非嚴格模式下,MySQL允許單引號及雙引號來引用字符串
eg: 'abc' 或 "abc"均可
非嚴格的grant模式自動創建用戶:在非嚴格模式下,MySQL允許grant語句中如果用戶不存在時自動創建用戶
eg: grant select on db1)tb1 to test;
非嚴格的存儲引擎自動替代: 在非嚴格模式下,MySQL允許指定的存儲引擎不可用是使用默認的存儲引擎替代
eg: create table tb2(id int primary key ) engin = aaa;
PS:還會有其他的非嚴格模式的組合以及不同數據庫的兼容模式情況,大家可以繼續探索。