SQL 模式(sql_mode)定義了 MySQL 服務器應遵循的 SQL 標準行為,影響數據驗證、錯誤處理、日期處理等核心特性。了解當前實例的 SQL 模式配置,對於遷移兼容性檢查、排查數據寫入異常、確保嚴格模式啟用等場景至關重要。本文示範如何查看並解讀 SQL 模式輸出。
在 MySQL 客戶端執行以下語句即可獲取當前會話或全域的 SQL 模式:
SELECT @@sql_mode;
或查看全域變量(需權限):
SHOW GLOBAL VARIABLES LIKE 'sql_mode';
mysql> SELECT @@sql_mode;
+----------------------------------------------------------------+
| @@sql_mode |
+----------------------------------------------------------------+
| STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION |
+----------------------------------------------------------------+
1 row in set (0.00 sec)
| 模式名稱 | 作用說明 |
|---|---|
STRICT_TRANS_TABLES |
嚴格模式核心。對於事務表,若插入/更新的數據無效(如超出範圍、類型不匹配),直接報錯並回滾;非事務表盡力截斷/調整並產生警告。強烈建議生產環境啟用,防止「靜默截斷」導致數據完整性受損。 |
NO_AUTO_CREATE_USER |
禁止 GRANT 語句自動創建新用戶(若無密碼)。MySQL 5.7+ 預設開啟,8.0 已移除此模式(行為內建化)。提升安全性,防止誤建空密碼賬號。 |
NO_ENGINE_SUBSTITUTION |
若 CREATE TABLE 或 ALTER TABLE 指定的存儲引擎不可用,拋出錯誤而非靜默替換為預設引擎(如 InnoDB)。避免因引擎缺失導致性能或功能預期落空。 |
ONLY_FULL_GROUP_BY:GROUP BY 查詢的選擇列必須出現在分組條件或聚合函數中(MySQL 5.7+ 預設開啟)。STRICT_ALL_TABLES:擴展嚴格模式至所有表(含非事務表),比 STRICT_TRANS_TABLES 更嚴格。ANSI_QUOTES:將雙引號 " 視為識別符引用符(如表名、列名),而非字符串引用符。PIPES_AS_CONCAT:將 || 視為字符串連接運算符而非邏輯 OR。會話級(當前連接生效,重連失效):
SET SESSION sql_mode = 'STRICT_TRANS_TABLES,ONLY_FULL_GROUP_BY';
全域級(持久化需寫入配置文件):
SET GLOBAL sql_mode = 'STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION';
配置文件持久化(my.cnf / my.ini):
[mysqld]
sql_mode = "STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,ONLY_FULL_GROUP_BY"
修改後需重啟 MySQL 服務生效。
STRICT_TRANS_TABLES 或 STRICT_ALL_TABLES),杜絕數據靜默截斷。ONLY_FULL_GROUP_BY,強制規範聚合查詢寫法,提升 SQL 可移植性。NO_ENGINE_SUBSTITUTION 以外的寬鬆模式,除非有明確的遷移兼容需求且經過充分測試。NO_AUTO_CREATE_USER),及時調整應用邏輯。通過 SELECT @@sql_mode; 可快速掌握實例的 SQL 行為標準。上述輸出顯示的三項模式構成了「嚴格事務、禁止自建用戶、拒絕引擎靜默替換」的穩健基線。理解各模式含義並按需組合,是維護數據質量與應用穩定的關鍵一環。