mysql 标识符规则_MySQL 标识符到底区分大小写么——官方文档告诉你
最近在阿里云服務器上部署一個自己寫的小 demo 時遇到一點問題,查看 Tomcat 日志后定位到問題出現在與數據庫服務器交互的地方,執行 SQL 語句時會返回 指定列.指定名 不存在的錯誤。多方查證后發現原來 MySQL 的標識符大小寫區分規則在 Unix 和 Windows 系統上是不同的。為了解決這個問題我去查看了 MySQL 官方給出的參考手冊后解決,同時為了學習我參考手冊中對應部分做了一次全面翻譯。
先說結論:在 Windows 操作系統中將 MySQL 的系統變量 lower_case_table_names 值修改為 2,并在開發時詳細規定好標識符名的大小寫規則。
標識符大小寫區分規則
在 MySQL 中,數據庫存儲在文件系統中的 data 目錄。每個數據庫對應一個子目錄,每張表對應一個子文件(也可能更多,取決于使用的存儲引擎)。觸發器也有對應文件。所以,數據庫、表和底層觸發器是否區分大小寫取決于底層操作系統。也就是說標識符在 Windows 系統中是大小寫不敏感的,在大多數 Unix 系統中是大小寫敏感的。MacOS 是一個特例,雖然它是基于 Unix 的系統,但是其默認文件系統(HFS+)是大小寫不敏感的。不過,MacOS 也支持 Unix 系統都支持的 UFS 文件系統。請參見 1.7.1 MySQL Extensions to Standard SQL 。此外,系統變量 lower_case_table_names 也會影響 MySQL 服務器是否區分標識符的大小寫,本章后續內容會介紹。
需要注意的是,盡管數據庫、表和觸發器名在某些平臺上不區分大小寫,也不應該在一個同一個語句中分別使用大寫和小寫。下面這行語句不會執行因為它同時使用了 my_table 和 MY_TABLE :
SELECT * FROM my_table WHERE MY_TABLE.col=1;
列、索引、存儲例程① 、事件名和列的別名無論在什么操作系統中都不區分大小寫。
此外,日志文件的名稱區分大小寫,這一點和標準 SQL 語言不同。
默認情況下,表名在 Unix 系統中大小寫敏感,在 Windows 和 MacOS 中不敏感。下面這行語句在 Unix 系統中不會執行,因為它同時使用 a 和 A 來做表的別名:
SELECT col_name FROM tbl_name AS a
WHERE a.col_name = 1 OR A.col_name = 2;
但是,在 Windows 操作系統中這行語句是可以執行的。為了避免這些不同引起的問題,最好采用一致的約定,比如創建和使用數據庫和表時都采用小寫字母,這樣的約定會最大程度的提升你代碼的跨平臺性(portability)和易用性(ease)。
數據庫和表名在磁盤上如何存儲和使用取決于 lower_case_table_names 系統變量,啟動 MySQL Server 后可以設置這個變量的值。下表 給出lower_case_table_names 的可選值和對應的含義。改變量的值不會影響觸發器的大小寫區分規則。在 Unix 系統中, lower_case_table_names 默認值為 0,在 Windows 系統中默認值是 1 。在 MacOS 中默認值為 2。
Value
Meaning
0
數據庫和表名的大小寫取決于 CREATE TABLE 和 CREATE DATABASE 語句中指明的大小寫,標識符名是大小寫敏感的。在 WIndos 或 MacOS 等文件系統大小寫不敏感的操作系統中不應將此變量的值設為 0,如果強行設置為 0,并且使用不同大小寫的字母訪問使用 MyISAM② 引擎的數據表,可能會導致索引損壞。
1
數據庫和表名以小寫形式存放在磁盤上,標識符名大小寫不敏感。此時 MySQL 執行 SQL 語句時會將所有的數據庫名、表名和表別名轉換成小寫。
2
數據庫和表名的大小寫取決于 CREATE TABLE 和 CREATE DATABASE 語句中指明的大小寫,但是執行查詢語句時 MySQL 會將其傳化成小寫,這種情況下標識符名不區分大小寫。這個值僅適用于文件系統大小寫不敏感的操作系統!當使用 InnDB② 引擎,數據表的具體表現和值為 1 時相同。
如果你只在一個平臺上使用 MySQL ,一般來說是不用修改 lower_case_table_names 的默認值的。但是在文件系統規則不同的平臺上轉移表時可能會發生錯誤。例如,在 Unix 系統中 my_table 和 MY_TABLE 是兩個不同的表,但是在 WIndows 系統上是同一個。有兩種方法可以保證在不同平臺上轉移數據時不發生錯誤:
在每個系統中都設置 lower_case_table_names = 1 ,不過這樣設置會導致執行 SHOW DATABASES 和 SHOW TABLES 語句不會正確返回創建時使用的大小寫區分。
在 Unix 系統上設置 lower_case_table_names = 0 ,Windows 系統上設置 lower_case_table_names = 2 。這樣能保留數據庫和表名的原始大小寫區分。 使用這種方法,您必須保證在 Windows 系統上執行語句時始終使用正確的大小寫區分。如果大小寫區分不當,將語句轉移到 Unix 系統時會發生錯誤。
**注意:**如果使用 InnDB 作為引擎,為了避免傳輸數據時發生的錯誤,應該在所有平臺上都設置 lower_case_table_names = 1 從而將標識符強制轉化成小寫。
如果您準備在 Unix 系統中設置 lower_case_table_names = 1 ,在設置完成之后、重啟 MySQL Server 之前必須手動將表名修改為小寫。使用 RENAME TABLE 語句完成:
RENAME TABLE T1 TO t1;
如果要修改一個或多個數據庫,請在設置 lower_case_table_names = 1 之前備份,然后刪除數據庫,在設置 lower_case_table_names = 1 之后重新加載數據庫:
使用 mysqldump 備份每一個需要重新創建的數據庫: mysqldump --databases db1 > db1.sql
mysqldump --databases db2 > db2.sql
...
使用 DROP DATABASE 語句刪除數據庫。
關閉 MySQL Server ,設置 lower_case_table_names 之后重啟服務器。
重新加載數據庫,由于修改了 lower_case_table_names 變量,每個數據庫和表名在重新創建時都會轉換成小寫。 mysql < db1.sql
mysql < db2.sql
...
如果標識符名的大寫形式在二進制規則排序后相等,則可以認為它們是重復的。這種情況在游標,條件,過程,函數,保存點,存儲例程的參數,存儲的程序局部變量和插件中適用。在列名,約束,數據庫,分區,預編譯語句③,表名,觸發器,用戶和用戶定義變量中是無效的④。
原文中使用的詞為 stored routine,筆者才疏學淺,不知道這個單詞表示什么,機翻得到的“存儲例程”。
MyISAM 和 InnDB 都是 MySQL 使用的數據庫引擎
原文中使用的詞為 statements prepared with PREPARE,猜測 JDBC 中的 PreparedStatement 對象就是來源于此,之后會挑時間查閱 MySQL 官方文檔學習。
總結
以上是生活随笔為你收集整理的mysql 标识符规则_MySQL 标识符到底区分大小写么——官方文档告诉你的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: datatable 导入mysql 解决
- 下一篇: mysql是哪五个字符集_MySQL中涉