MySQL 是否大小写敏感

本文未做特别说明的,指同时适用于 MySQL 5.7 和 MySQL 8.x。

先说结论:

  • 数据库、表名(包括别名)、触发器名是否大小写敏感与操作系统以及 MySQL 配置有关。
  • 列名(包括别名)、索引、存储过程和事件名称大小写不敏感。
  • 字段内容大小写是否敏感与字符集排序规则有关。

MySQL 大小写规则

在 MySQL 中,数据库对应于数据目录中的目录。数据库中的每个表对应于数据库目录中的至少一个文件(也可能更多,具体取决于存储引擎)。触发器也对应于文件。因此,底层操作系统的大小写敏感度会影响数据库、表和触发器名称的大小写敏感度。这意味着此类名称在 Windows 中不区分大小写,但在大多数 Unix 版本中区分大小写。一个值得注意的例外是 macOS,它基于 Unix,但使用不区分大小写的默认文件系统类型 (HFS+)。

列、索引、存储过程和事件名称在任何平台上都不区分大小写,列别名也不区分大小写。

lower_case_table_names 系统变量

表和数据库名称如何存储在磁盘上以及如何在 MySQL 中使用受到 lower_case_table_names 系统变量的影响,但该变量不影响触发器标识符的大小写敏感性。

lower_case_table_names 在 Unix 上,默认值为 0。在 Windows 上,默认值为 1。在 macOS 上,默认值为 2。

含义
0表和数据库名称使用以大小写敏感的形式存储在磁盘上,名称比较(比如查询)时区分大小写。如果在文件名不区分大小写的系统(例如 Windows 或 macOS)上运行 MySQL,则不应将此变量设置为 0 。如果在不区分大小写的文件系统上强制将变量 lower_case_table_names 设置为 0,并在基于 MyISAM 数据引擎的表使用不同的字母大小写访问表名,则可能会导致索引损坏。
1表名称以小写形式存储在磁盘上,名称比较不区分大小写。MySQL 在存储和查找时将所有表名转换为小写。此行为也适用于数据库名称和表别名。
2表和数据库名称使用以大小写敏感的形式存储在磁盘上,但 MySQL 在查找时将它们转换为小写。名称比较不区分大小写。这仅适用于不区分大小写的文件系统!基于 InnoDB 数据引擎的表名和视图名以小写形式存储,正如 lower_case_table_names = 1 的情况。

另外需要注意的一点是,在 MySQL 8 中 lower_case_table_names 变量只能在MySQL服务器初始化时配置,初始化后不允许修改。所以,如何配置该参数要提前规划好,防止后续修改时需要数据迁移,导致其他问题。

MySQL 的字符集与排序规则

通俗讲字符集就是字符码的集合,在 MySQL 中字符集的选择影响字符码的存储,字符集选择不好不仅影响存储,连展示都会有问题,例如乱码。

在业务中常用的字符集是 UTF-8 字符集,MySQL 有两种这样的字符集:utf8、utf8mb4,它们的区别如下:

  • utf8: 支持最长 3 Byte 的字符编码,但一部分 UTF-8 的 4 Byte 编码不支持,例如 emoji。
  • utf8mb4:支持最长 4 Byte 的字符编码。这是业务中使用最多的字符集,从 MySQL 8.0 开始成为默认字符集。

而字符的排序规则决定了字符在比较、排序时以及大小写敏感的规则。涉及字符比较的操作均与其相关,例如:排序、分组、索引、比较(=、>、<等)。

在 MySQL 中字符集的排序规则,决定了字段是否大小写敏感。这些排序规则一般以相关的字符集名开始,通常包括一个语言名,并且以 _ci_cs_bin 结束 。

  • ci 为 case insensitive 的缩写,即大小写不敏感。
  • cs 为 case sensitive的缩写,即大小写敏感。
  • bin 将字符串中的每一个字符用二进制数据存储,区分大小写。

举例来说,当使用 utf8mb4 字符集,默认的字段排序规则是 utf8mb4_general_ci,即字符大小写不敏感。

-- 所有字段都是 utf8mb4 字符集,且均使用 utf8mb4_general_ci 排序规则
create table user(id int(11) not null auto_increment,username varchar(127) default null,nickname varchar(127) default null,primary key (id),unique key uniq_idx_username (username)
) engine=innodb default charset=utf8mb4;

我们可以插入几条数据进行测试:

INSERT INTO `user` (`username`) VALUES ('user');
INSERT INTO `user` (`username`) VALUES ('User');
INSERT INTO `user` (`username`) VALUES ('USER');

使用查询语句查询 username 为全部小写的 user 的用户,结果三条记录全部都查询到了,这是因为此时所有字段是大小写不敏感的。

mysql> SELECT username from user where username = 'user';
+----------+
| username |
+----------+
| user     |
| User     |
| USER     |
+----------+
3 rows in set

那么,我想要只搜索出 username 为 user 的用户该怎么做呢?

解决方案就是使用 BINARY 关键字来指定字符字段的排序规则:

mysql> select * from user where BINARY username ='user';
+----+----------+
| id | username |
+----+----------+
|  1 | user     |
+----+----------+
1 row in set

这种方式相对较简单,不用改动表结构,只需在需要区分查询的字段前加上关键字。但这种方式也是有缺点的,每次写查询的时候都要注意加关键字,而且可能需要改动较多的代码。

另一种方式是在建表时就对 username 字段进行限制:

-- 均使用 utf8mb4_general_ci 排序规则
CREATE TABLE USER (id INT (11) NOT NULL auto_increment,username VARCHAR (127) BINARY NOT NULL,nickname VARCHAR (127) DEFAULT NULL,PRIMARY KEY (id),UNIQUE KEY uniq_idx_username (username) 
) ENGINE = INNODB DEFAULT charset = utf8mb4;

如果需要整个表都是大小写敏感的,可以在创建表时使用 utf8mb4_bin 排序规则。

create table user(id int(11) not null auto_increment,username varchar(127) default null,nickname varchar(127) default null,primary key (id),unique key uniq_idx_username (username)
) engine=innodb default charset=utf8mb4 COLLATE=utf8mb4_bin;
-- 指定 COLLATE=utf8mb4_bin 即可

一些想法

如何设置 lower_case_table_names 参数?

对于 lower_case_table_names 参数设置为 0 可能会带来哪些问题呢?

比如说:一位同事创建了 Test 表,另一位同事在写程序调用时写成了 test 表,则会报错不存在,更甚者可能会出现 TestDb 库与 testdb 库共存,Test 表与 test 表共存的情况,这样就更加混乱了。所以为了实现最大的可移植性和易用性,我们可以采用一致的约定,例如始终使用小写名称创建和引用库表。也可以将 lower_case_table_names 设为 1 来解决此问题。

另外,上面提到了使用小写的表名,这也是阿里的 Java 开发手册推荐的用法。但如果我们还要考虑其他数据库的兼容,比如 Oracle 呢?这时,保持小写表名就不是一个好想法了。

因为,在 Oracle 中,如果表名和字段名在定义的时候是小写的,那么 SQL 操作时候,表名和字段名是需要用引号括起来的。

参考

  • MySQL 5.7 官方文档
  • MySQL 8.2 官方文档
  • MySQL 的字符集与排序规则
  • 关于 MySQL 库表名大小写问题
  • MySQL 大小写参数 lower_case_table_names 学习
  • MySQL 转 Oracle 遇到的问题:表名长度及大小写问题

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/132780.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

高数笔记06:无穷级数

图源&#xff1a;文心一言 时间比较紧张&#xff0c;仅导图~~&#x1f95d;&#x1f95d; 第1版&#xff1a;查资料、画导图~&#x1f9e9;&#x1f9e9; 参考资料&#xff1a;《高等数学 基础篇》武忠祥 &#x1f433;目录 &#x1f433;常数项级数 &#x1f40b;概要 &…

C++基础——对于C语言缺点的补充(2)

上篇文章中说到&#xff0c;为了解决C语言会出现人为定义的函数和库函数出现重定义的错误&#xff0c;C引入了一个新的概念&#xff0c;即命名空间&#xff0c;通过认为定义命名空间&#xff0c;来解决上述问题。 在本篇文章中&#xff0c;将继续介绍C相对于C语言不足来进行的补…

Node.js、Chrome V8 引擎、非阻塞式I/O介绍

目录 Node.js介绍Chrome V8 引擎介绍非阻塞式I/O介绍 &#x1f44d; 点赞&#xff0c;你的认可是我创作的动力&#xff01; ⭐️ 收藏&#xff0c;你的青睐是我努力的方向&#xff01; ✏️ 评论&#xff0c;你的意见是我进步的财富&#xff01; Node.js介绍 Node.js 是一个…

Harbor企业级Registry基础镜像仓库的详细安装使用教程(保姆级)

Harbor Docker 官方提供的私有仓库 registry&#xff0c;用起来虽然简单 &#xff0c;但在管理的功能上存在不足。 Harbor是vmware一个用于存储和分发Docker镜像的企业级Registry服务器&#xff0c;harbor使用的是官方的docker registry(v2命名是distribution)服务去完成。 ha…

数据结构之堆的实现(图解➕源代码)

一、堆的定义 首先明确堆是一种特殊的完全二叉树&#xff0c;分为大根堆和小根堆&#xff0c;接下来我们就分别介绍一下这两种不同的堆。 1.1 大根堆&#xff08;简称&#xff1a;大堆&#xff09; 在大堆里面&#xff1a;父节点的值 ≥ 孩子节点的值 我们的兄弟节点没有限制&…

pandas 笔记:get_dummies分类变量one-hot化

1 函数介绍 pandas.get_dummies 是 pandas 库中的一个函数&#xff0c;它用于将分类变量转换为哑变量/指示变量。所谓的哑变量&#xff0c;就是将分类变量的每一个不同的值转换为一个新的0/1变量。在输出的DataFrame中&#xff0c;每一列都以该值的名称命名 pandas.get_dummi…

java使用bouncycastle加解密

jdk默认带了一些常见的加解密方式&#xff0c;当我们常见的加解密不能满足时&#xff0c;就需要用到一些第三方的库了&#xff0c;bouncycastle就是其中一种。 但是bouncycastle文档比较少。简单介绍一下写法 1.导入依赖 <dependency><groupId>org.bouncycastle&…

5 ip的分配

如上一节所述&#xff0c;需要和其他设备通信&#xff0c;那么需要先配置ip. 1、如何配置ip 1.可以使用 ifconfig&#xff0c;也可以使用 ip addr 2.设置好了以后&#xff0c;用这两个命令&#xff0c;将网卡 up 一下&#xff0c;就可以了 //---------------------------- 使…

AI大模型时代网络安全攻防对抗升级,瑞数信息变革“下一代应用与数据安全”

AI与大模型技术加速普及&#xff0c;安全领域也在以创新视角聚焦下一代应用安全WAAP变革&#xff0c;拓展新一代数据安全领域。近日瑞数信息重磅发布了瑞数全新API扫描器、API安全审计、数据安全检测与应急响应系统及分布式数据库备份系统四大新品。此次发布在延续瑞数信息Bot自…

用java代码实现QQ第三方登录

QQ第三方登录需要使用到QQ互联开放平台提供的API&#xff0c;在Java中可以使用OAuth2.0协议来实现第三方登录。 具体实现步骤如下&#xff1a; 注册QQ互联开放平台账号&#xff0c;并创建应用&#xff0c;获取到App ID和App Secret。 在Java项目中导入QQ互联开放平台提供的Ja…

当zmq 和 docker 都要绑定一个端口时,怎么不修改端口号就能解决冲突?

问题描述 docker容器中的程序需要和外部进行通讯&#xff0c;但是当作为请求方向 响应方发送数据时&#xff0c;外部的进程因为需要绑定的端口被docker占用而绑定失败。 解决方式 方式一&#xff1a;使用请求响应方式&#xff0c;但是将响应端放置到容器内部。 方拾二&#…

freertos简单串口

先来完善一下FreeRTOSConfig.h这个配置文件 /*FreeRTOS V9.0.0 - Copyright (C) 2016 Real Time Engineers Ltd.All rights reservedVISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION.This file is part of the FreeRTOS distribution.FreeRTOS is …

vue3+ts+vite搭建项目

检查node版本 > node -v检查vue版本 > vue -V1、全局安装Vue CLI 3.X版本 > npm install -g vue/cli2、创建vue 项目 > vue create [project-name]3、安装vite > npm install vite4、使用vite Vite 需要 Node.js 版本 > 12.0.0。 > npm init vitela…

通信原理板块——时域均衡

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 1、均衡器 为了减小码间串扰的影响…

放卷开环张力控制(伺服转矩模式应用)

收放卷张力开环闭环控制算法,请参考下面文章链接: PLC张力控制(开环闭环算法分析)_RXXW_Dor的博客-CSDN博客文章浏览阅读4k次,点赞3次,收藏3次。里工业控制张力控制无处不在,也衍生出很多张力控制专用控制器,磁粉制动器等,本篇博客主要讨论PLC的张力控制相关应用和算…

Scala和Play WS库编写的爬虫程序

使用Scala和Play WS库编写的爬虫程序&#xff0c;该程序将爬取网页内容&#xff1a; import play.api.libs.ws._ import scala.concurrent.ExecutionContext.Implicits.global ​ object BaiduCrawler {def main(args: Array[String]): Unit {val url ""val proxy…

CMake教程-第 12 步:打包调试和发布

CMake教程-第 12 步&#xff1a;打包调试和发布 1 CMake教程介绍2 学习步骤[Step 1: A Basic Starting Point](https://blog.csdn.net/u014100559/article/details/133099915?spm1001.2014.3001.5501)[Step 2: Adding a Library](https://blog.csdn.net/u014100559/article/de…

【学习笔记】[COCI2018-2019#1] Teoretičar

首先&#xff0c;可以发现 C C C等于所有点度数的最大值&#xff0c;我们能用到的颜色数目为 2 x ≥ C 2^x\ge C 2x≥C。 考虑分治&#xff0c;将边集划分为 E E 1 E 2 EE_1E_2 EE1​E2​&#xff0c;使得 E 1 , E 2 E_1,E_2 E1​,E2​中点度数的最大值都不超过 2 x − 1 2^…

06.Oracle数据备份与恢复

Oracle数据备份与恢复 一、通过RMAN方式备份二、使用emp/imp和expdb/impdb工具进行备份和恢复三、使用Data guard进行备份与恢复 一、通过RMAN方式备份 通过 RMAN&#xff08;Oracle 数据库备份和恢复管理器&#xff09;方式备份 Oracle 数据库&#xff0c;可以使用以下步骤&a…

网速和带宽浅析

经常会对交换机的带宽和文件的存储的单位混淆不清&#xff0c;下面进行整理分析。 1、网速 网速是通俗的叫法&#xff0c;专业的叫法是带宽。如手机上显示的网速为2.4K/s。 带宽通常有十兆、百兆、千兆&#xff0c;即10Mbps、100Mbps、1000Mbps&#xff0c;单位为bps。 2、带…