從 MySQL 遷移到 GoldenDB,這個參數記得改!
大家好,我是君哥。
最近從 MySQL 遷移到 GoldenDB,踩過一個坑。之前分享過。再來回顧一下。
事故現場
我們先創建一張表 test_1,SQL 如下:
CREATE TABLE`test_1` (
`id`int(8) NOTNULL AUTO_INCREMENT,
`column1`varchar(1) COLLATE utf8_bin DEFAULTNULL,
`date_time` datetime DEFAULTNULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11DEFAULTCHARSET=utf8 COLLATE=utf8_bin往 test_1 插入 1 條數據,如下圖:
INSERT INTO test_1(column1,date_time)VALUES ('a',NOW());然后我們創建一張跟 test1 表結構一樣的表 test2,
CREATE TABLE test_2 LIKE test_1;執行下面 SQL,
insert into test_2(column1,date_time) select "column1", now() from test_1;這條 SQL 并不復雜,從 test1 表查出數據寫到 test2 表。但不知道寫代碼的小伙伴出于什么考慮在 column1 上加了雙引號。這個 SQL 在 MySQL(8.0 版本)上執行是沒有問題的,但是放到了 GoldenDB 上就報錯了,因為雙引號包著的字段返回的是 column1 這個字符串,最終字段超長報錯(Data too long for column 'column1' at row 1)。
問題根因
如果這個坑直接甩鍋給 GoldenDB,并不合適。為什么這么說呢?公司專業的 DBA 大佬給了解答,之所以這個 SQL 在 MySQL 上運行沒問題,在 GoldenDB 上就會出錯,是因為 ANSI_QUOTES 這個參數配置不一致。
ANSI_QUOTES 是 MySQL 數據庫中的 SQL 模式選項,用于調整標識符與字符串常量的引用規則,使其符合 ANSI SQL 標準。可以使用下面的 SQL 臨時開啟:
-- 僅對當前會話開啟
SET SESSION sql_mode = 'ANSI_QUOTES';
-- 對之后的所有新連接生效(重啟后失效)
SET GLOBAL sql_mode = 'ANSI_QUOTES';或者修改配置文件開啟,這樣可以永久生效。
ANSI_QUOTES 介紹
開啟
開啟 ANSI_QUOTES 后,雙引號 (") 被解釋為標識符引號,作用與反引號 (`) 相同,用于引用數據庫、表、字段等名稱。例如下面 SQL 中的 name 被解釋為列名,而 my_table 被解釋為表名。
SELECT "name" FROM "my_table";而單引號則被解釋為字符串,比如下面 SQL 查找結果返回 name 這個字符串:
SELECT 'name' FROM my_table;關閉
關閉 ANSI_QUOTES 后(默認關閉),雙引號 (") 被解釋為字符串引號,與單引號 (') 的作用完全相同。反引號 (`) 被用于引用標識符(如數據庫名、表名、字段名)。下面的兩個 SQL 返回的都是 name 這個字符串:
SELECT 'name' FROM my_table;
SELECT "name" FROM my_table;為什么要使用 ansi_quotes 呢?主要有 2 個原因:
1.兼容性和可移植性
如果你的應用程序需要與多種遵循 ANSI SQL 標準的數據庫(如 PostgreSQL, Oracle, GoldenDB)保持兼容,啟用 ANSI_QUOTES 會很有幫助。這可以統一使用雙引號來引用標識符,而不用擔心數據庫遷移會發生因為引號導致的異常。在信創改造的大背景下,這個參數作用很大。
2.SQL 規范
一些開發團隊要求必須遵循 SQL 標準,明確區分單引號用于字符串,雙引號用于標識符。這可以使 SQL 的意圖更加清晰,減少歧義。
總結
ANSI_QUOTES 是 MySQL 數據庫中的 SQL 模式選項,用于調整標識符與字符串常量的引用規則,使其符合 ANSI SQL 標準。這個配置開啟,對于 SQL 規范化和數據庫遷移很有幫助。
























