MySQL 标识符到底区分大小写么——官方文档告诉你
最近在阿里云服务器上部署一个自己写的小 demo 时遇到一点问题,查看 Tomcat 日志后定位到问题出现在与数据库服务器交互的地方,执行 SQL 语句时会返回 指定列.指定名
不存在的错误。多方查证后发现原来 MySQL 的标识符大小写区分规则在 Unix 和 Windows 系统上是不同的。为了解决这个问题我去查看了 MySQL 官方给出的参考手册后解决,同时为了学习我参考手册中对应部分做了一次全面翻译。
先说结论:在 Windows 操作系统中将 MySQL 的系统变量 lower_case_table_names
值修改为 2,并在开发时详细规定好标识符名的大小写规则。
下面是翻译文章,原文链接:MySQL :: MySQL 5.6 Reference Manual :: 9.2.2 Identifier Case Sensitivity
标识符大小写区分规则
在 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优化(出自官方文档) - 第九篇(优化数据库结构篇)
目录 Mysql优化(出自官方文档) - 第九篇(优化数据库结构篇) 1 Optimizing Data Size 2 Optimizing MySQL Data Types 3 Optimizing ...
- Mysql优化(出自官方文档) - 第一篇(SQL优化系列)
Mysql优化(出自官方文档) - 第一篇 目录 Mysql优化(出自官方文档) - 第一篇 1 WHERE Clause Optimization 2 Range Optimization Skip ...
- 看MySQL官方文档的示例SQL有感
[背景] 周末比较闲,我这个人又没有什么爱好,当然了读书除外:前一些天我一个同事说:“你一个dba想去写一本“django”书,合适吗?” 我想也是,一个人不能忘了本,所以MySQL还是要好好的搞一搞 ...
- Mysql优化(出自官方文档) - 第三篇
目录 Mysql优化(出自官方文档) - 第三篇 1 Multi-Range Read Optimization(MRR) 2 Block Nested-Loop(BNL) and Batched K ...
- Mysql优化(出自官方文档) - 第五篇
目录 Mysql优化(出自官方文档) - 第五篇 1 GROUP BY Optimization 2 DISTINCT Optimization 3 LIMIT Query Optimization ...
- Mysql优化(出自官方文档) - 第八篇(索引优化系列)
目录 Mysql优化(出自官方文档) - 第八篇(索引优化系列) Optimization and Indexes 1 Foreign Key Optimization 2 Column Indexe ...
- 从官方文档中探索MySQL分页的几种方式及分页优化
概览 相比于Oracle,SQL Server 等数据库,MySQL分页的方式简单得多了,官方自带了分页语法 limit 语句: select * from test_t LIMIT {[offset ...
- 手把手教你看MySQL官方文档
前言: 在学习和使用MySQL的过程中,难免会遇到各种问题.不知道当你遇到相关问题时会怎么做,我在工作或写文章的过程中,遇到不懂或需要求证的问题时通常会去查阅官方文档.慢慢的,阅读文档也有了一些经验, ...
- Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇)
Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 目录 Mysql优化(出自官方文档) - 第十二篇(优化锁操作篇) 1 Internal Locking Methods Row-Leve ...
随机推荐
- HBase的基本使用(安装配置、启动关闭、hbash shell的基本操作、phoenix、实战)
HBase的前提条件: JDK SSH Hadoop JDK:Hadoop和JDK运行的环境,他们的守护进程运行在JVM下.HBase支持JDK 1.6以上的版本.比如: jdk-8u161-linu ...
- git 常用命令 command
git config --list //查看配置信息 git config user.name //查看用户名 git config user.email //查看用户邮箱 从远程克隆到本地仓库 ...
- 第三篇 Scrum 冲刺博客
一.站立式会议 1. 会议照片 2. 工作汇报 团队成员名称 昨日(24日)完成的工作 今天(25日)计划完成的工作 工作中遇到的困难 陈锐基 - 个人信息编辑后与组件关联- 表白墙数据用 Vuex ...
- python web的一些常见技术面试笔试题
1. 三次握手四次挥手 tcp建立连接的过程是三次挥手,断开连接是4次挥手. 三次握手:建立连接时 a. 客户端发送syn=1 seq=k给服务器 b. 服务器接收到之后知道有客户端想建立连接, ...
- P5327 [ZJOI2019]语言
一边写草稿一边做题吧.要看题解的往下翻,或者是旁边的导航跳一下. 草稿 因为可以开展贸易活动的条件是存在一种通用语 \(L\) 满足 \(u_i\) 到 \(v_i\) 的最短路径上都会 \(L\) ...
- 题解-CTS2019 珍珠
题面 CTS2019 珍珠 有 \(n\) 个在 \([1,d]\) 内的整数,求使可以拿出 \(2m\) 个整数凑成 \(m\) 个相等的整数对的方案数. 数据范围:\(0\le m\le 10^9 ...
- python的数据缓存
Python的数据缓存 python 的内置数据类型,数值型,字符串,列表,字典等都会有自己的对象缓存池, 这样做的好处是,避免了频繁的申请内存,释放内存,这样会极大的降低应用程序的运行速度,还会造成 ...
- react项目中对dom元素样式修改的另一种方法以及将组件插入到node节点中
在项目中,以前如果遇到对dom元素的操作都是直接获取dom元素,比如说: 但是如果修改的样式比较多的话,不如直接"切换"dom元素,如下例子: 这样会节省一些性能.因为操作dom的 ...
- [日常摸鱼]UVA11424&11426 GCD - Extreme
话说UVa的机子跑的好快呀- (两题题意一样,前一题数据范围比较小) 题意:求$\sum_{i=1}^{n-1} \sum_{j=i+1}^n gcd(i,j),n<4\times 10^6$ ...
- Python高级语法-多继承MRO相关-多继承顺序(4.5.1)
@ 目录 1.说明 2.代码 关于作者 1.说明 使用类的魔法方法__mro__ 可以查看他的父类调用顺序 还有调用父类的构造方法的时候,使用super调用,里面有C3算法支持,不会重复调用相同的祖先 ...