MySQL唯一索引大小写敏感性问题及字符集深入解析

news/2024/9/15 11:45:48/ 标签: mysql, 数据库, 字符集, 排序规则, 大小写区分
1. 问题背景与描述

在实际生产环境中,我们遇到了一个插入重复异常的问题。具体表现在长链接转换为短链接的过程中,生成的短链被插入数据库时触发了唯一索引的冲突错误。错误的根本原因在于数据库使用了不区分大小写的排序规则,导致两个看似不同的短链“7rrBcCZ0s”和“7rrbcCZ0s”被错误地认为是相同的值,从而引发了插入失败的情况。

2. 问题分析

此问题的根本原因是MySQL默认使用的不区分大小写(case insensitive,简称_ci)的排序规则。具体来说,MySQL的默认排序规则使得所有字符被视为不区分大小写,因此当短链生成包含大小写混合的字符串时,系统无法正确区分它们,导致唯一索引判断出错。

2.1 MySQL排序规则的分类
  • _ci (case insensitive):不区分大小写。 这是大多数情况下MySQL的默认排序规则utf8mb4_general_ci是一个常见的例子。
  • _cs (case sensitive):区分大小写。 在这种规则下,大小写不同的字符会被认为是不同的。utf8mb4_general_cs就是这样的一个排序规则
  • _bin (binary):二进制排序,区分大小写。 这是最严格的排序规则,不仅区分大小写,还会精确到二进制级别。utf8mb4_bin就是一个例子。
3. 解决方案

为了避免此类问题,必须在涉及敏感数据的字段上使用区分大小写的排序规则。具体操作是将表中对应字段的字符集设置为utf8mb4,并使用_bin排序规则

SQL命令:

ALTER TABLE `long_short_url_map` 
MODIFY COLUMN `long_url` varchar(512) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin 
NULL DEFAULT NULL COMMENT '长链地址', ALGORITHM=INPLACE, LOCK=NONE,
MODIFY COLUMN `short_url` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin 
NULL DEFAULT NULL COMMENT '短链地址', ALGORITHM=INPLACE, LOCK=NONE;

通过将排序规则设置为_bin,可以确保在插入或查询时,系统能正确区分大小写不同的字符串,从而避免插入冲突。

4. 如何避免类似问题

数据库设计阶段,应充分考虑字符集排序规则的选择:

  • 敏感数据明确使用_bin排序规则 对于需要区分大小写的字段,建议直接使用_bin排序规则,确保数据的唯一性和准确性。
  • 表设计时明确字符集排序规则 在设计数据库表时,开发人员应明确设定表的字符集排序规则,避免使用默认值,以防产生潜在问题。
  • 了解应用场景: 根据具体应用场景选择合适的字符集排序规则。例如,在用户密码、验证码、短链等场景下,通常需要区分大小写。
5. MySQL字符集排序规则知识详解
5.1 字符集(Character Set)

字符集决定了数据库如何存储和展示字符。常见的字符集有:

  • latin1: 主要用于西欧语言的字符集,单字节编码。
  • utf8: 可以表示绝大多数文字(多字节编码),但并不完整支持所有Unicode字符。
  • utf8mb4: 完全支持所有Unicode字符,包括表情符号等多字节字符。
5.2 排序规则(Collation)

排序规则定义了字符在数据库中的比较和排序方式。根据排序规则的不同,同一个字符集可以有不同的排序规则排序规则后缀通常为:

  • _ci: 不区分大小写。
  • _cs: 区分大小写。
  • _ai: 不区分重音符号。
  • _as: 区分重音符号。
  • _bin: 二进制排序,区分大小写。
5.3 选择字符集排序规则的最佳实践
  • 默认使用utf8mb4字符集 utf8mb4字符集不仅支持常见的文字,还能存储Emoji等特殊字符,适用于现代化的Web应用。
  • 根据业务场景选择排序规则 例如,在用户登录系统中,用户名通常使用不区分大小写的排序规则_ci),而在存储用户密码或验证码时,则应使用区分大小写的排序规则_cs_bin)。
6. 总结

数据库设计和开发过程中,字符集排序规则的选择至关重要。错误的选择可能导致数据误判、查询不准确等问题。通过正确选择和使用MySQL的字符集排序规则,可以有效避免诸如唯一索引冲突等问题,提高系统的稳定性和数据准确性。在实际项目中,开发人员应深入理解MySQL字符集排序规则的工作原理,并根据业务需求进行合理配置。


http://www.ppmy.cn/news/1519396.html

相关文章

Linux下安装MySQL8.0

一、安装 1.下载安装包 先创建一个mysql目录,在将压缩包下载到此 # 下载tar包 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz等待下载成功 2.解压mysql8.0安装包 tar xvJf mysql-8.0.20-linux-glibc2.12-x86…

尝试用java spring boot+VUE3实现前后端分离部署

前言 这几天开学了,公司这边几个和学校对接的项目都挺忙的,然后我又开始有点闲的情况了。问大佬能不能继续看看若依的项目,大佬让我自己去学了。在看若依的项目的时候在想,python的FLASK后端实现和JAVA spring boot的实现差别大不…

【GPT】Coze使用开放平台接口-【2】创建工作流-语音伪造检测工作流

在Coze使用开放平台接口-【1】创建插件,我们已经成功创建了开放平台的插件,也创建了对应的工具。本文档就根据创建好的插件,来创建对应的工作流,来让接口能够用起来。 下面直接用现成的插件快商通AI开放平台,来创建语音…

深度学习实战1--决策树与随机森林(最新版本不报错)

1.乳腺癌数据集简介 乳腺癌数据集包含了美国威斯康星州记录的569个病人的乳腺癌的病情,包含30个维度的生理指标数据(特征),以及乳腺癌是恶性还是良性的标签。因为这是一个二分类问题, 也叫二类判别数据集。 2.实战任务 这数据主要包含569个样本。每个样…

【3.6】贪心算法-解救生艇问题

一、题目 第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。 每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit 。 返回载到每一个人所需的最小船数。(保证每个人都能被船载)。 二、解题思路 题目要求每艘船最多能载两人&…

安美数字酒店宽带运营系统-任意文件读取

漏洞描述: 安美数字酒店宽带运营系统 weather.php 接口存在任意文件读取漏洞,未经身份验证攻击者可通过该漏洞读取系统重要文件(如数据库配置文件、系统配置文件)、数据库配置文件等等,导致网站处于极度不安全状态 fo…

c++中的匿名对象及内存管理及模版初阶

目录 c中的匿名对象 日期到天数的转换 深入理解析构 深入理解拷贝构造 内存管理 全局变量和static变量的区别; malloc/calloc/realloc的区别 new和delete的意义? operator new与operator delete函数 对比malloc和new operator 定制operator ne…

OceanBase 功能解析之 Binlog Service

前言 MySQL,是在全球广泛应用的开源关系型数据库,除了其稳定性、可靠性和易用性,他早期推出的二进制日志功能,即binlog,也是MySQL广受欢迎的原因。 MySQL binlog,即二进制日志,是 MySQL 中用于…

django之ForeignKey、OneToOneField 和 ManyToManyField

在Django中,ForeignKey、OneToOneField 和 ManyToManyField 是用于定义模型之间关系的字段类型。 ForeignKey ForeignKey 用于定义多对一的关系。例如,一个Employee可以属于一个Department,一个Department可以有多个Employee。 from djang…

String的基本特;String的内存分配;字符串拼接操作;intern()的使用;经典面试题

目录 String的基本特性String的内存分配字符串拼接操作intern()的使用经典面试题 String的基本特性 创建的两种方式 String s “a” //字面量的定义方式 String s2 new String(“fd”) String类声明为final,不可被继承,实现了Serializable接口&#xf…

昇腾AI处理器的计算核心 - AI Core即DaVinci Core

昇腾AI处理器的计算核心 - AI Core即DaVinci Core flyfish 从一段代码的解释开始 template <typename T> class GlobalTensor { public:void setGlobalBuffer(T* buffer, uint32_t buffersize) {// 在这里实现设置全局缓冲区的逻辑} };语法的说明&#xff0c;主要用于…

优化 Webpack 打包体积的思路

在现代前端开发中&#xff0c;优化 Webpack 打包体积是提升应用性能的重要手段。以下是一些有效的优化思路&#xff1a; 提取第三方库&#xff1a;将第三方库单独打包&#xff0c;并通过 CDN 引入。这样不仅减少了打包体积&#xff0c;还利用了 CDN 的缓存优势&#xff0c;提高…

索迪迈科技油罐车监控系统中车载摄像头的布局策略

随着科技的不断发展&#xff0c;车载监控系统在油罐车上的安装已经成为了一种趋势。这不仅大大降低了车辆的安全隐患与运营成本&#xff0c;更对石油运输企业优化资源配置、提高市场竞争力起到了积极的促进作用。那么&#xff0c;在油罐车监控系统中&#xff0c;如何合理布局车…

html table tbody deleteRow有残留?

html table tbody deleteRow有残留? 问题描述&#xff1a;这个问题描述的是在使用 HTML 的 deleteRow 方法从一个 table 的 tbody 中删除行时&#xff0c;表格中仍然存在某些行。 参考方法1&#xff1a;表格移除多行的时候, 移除行数字索引顺序要从大到小, 而不能从小到大。 …

【华为OD】2024D卷——查找众数与中位数

题目&#xff1a; 众数是指一组数据中出现次数量多的那个数&#xff0c;众数可以是多个。 中位数是指把一组数据从小到大排列&#xff0c;最中间的那个数&#xff0c;如果这组数据的个数是奇数&#xff0c;那最中间那个就是中位数&#xff0c;如果这组数据的个数为偶数&#xf…

【我的Android进阶之旅】使用TabLayout自定义一个TitleTabView

文章目录 零、效果图一、自定义一个TitleTabView1.1 自定义属性(attrs.xml 中)1.2 自定义TitleTabView1.3 TabItem的子布局1.4 颜色值二、在 XML 中使用 `TitleTabView`2.1 布局文件(XML)2.1.1属性说明三、在 Kotlin 中使用 `TitleTabView`:零、效果图 其中Tab 2是选中的效果…

【笔记】数据结构——8月27日

toc 静态链表 静态链表的存储结构 #define maxn 15struct space {int cur;int key; }s[maxn];int LocateElem_SL(SLinkList *s,ElemType e) {//在静态链表中查找第一个值为e的元素//若找到&#xff0c;则返回它在链表中的位置&#xff0c;否则返回0 is[0].cur;while(i&…

使用本地IP无法访问前端项目的问题

说明&#xff1a;记录一次使用本机IP无法访问前端项目的问题 场景&解决 前端项目在我本机电脑上部署完成&#xff0c;我想通过局域网的IP把地址发给测试&#xff0c;发现使用localhost和127.0.0.0都能访问到前端项目&#xff0c;但是这个地址只能在自己的电脑上访问。 解…

记一次学习--webshell绕过(利用清洗函数)

目录 样本 样本修改 样本 <?php $a array("t", "system"); shuffle($a); $a[0]($_POST[1]); 通过 shuffle 函数打乱数组,然后通过$a[0]取出第一个元素&#xff0c;打乱后第一个元素可能是t也可能是system。然后再进行POST传参进行命令执行。 这里抓…

使用 Puppeteer 在 PHP 中解决 reCAPTCHA 以进行网页抓取

您是否在抓取数据时遇到 reCAPTCHA 障碍&#xff1f;我也遇到过。这些 CAPTCHA 挑战会将简单的抓取任务变成一大障碍。但别担心&#xff0c;我有一个解决方案可以帮助您轻松绕过这些障碍。 在本博文中&#xff0c;我将引导您使用 Puppeteer&#xff08;一个功能强大的 Node.js…