mysql设置字段的排序规则对大小写敏感

Posted FightingDeng2022

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql设置字段的排序规则对大小写敏感相关的知识,希望对你有一定的参考价值。

在开发中遇到一个问题:在插入一张表中提示主键冲突了,对数据分析了很久,没有发现问题。后面发现是数据库设计的时候设定的排序规则指定的是 COLLATE=utf8_general_ci,而不是用 COLLATE=utf8_bin,这两个规则的区别是什么呢?

  1. utf8_general_ci:这个排序规则是不区分大小写的,也就是说,在比较和排序字符串时,不考虑字符的大小写差异。例如,"A"和"a"会被认为是相同的。
  2. utf8_bin:这个排序规则是区分大小写的,也就是说,在比较和排序字符串时,会考虑字符的大小写差异。例如,"A"和"a"会被认为是不同的。它直接按照字符的二进制值进行比较和排序,不考虑语言特定的规则。
    实际测试一下:
    先建立一张指定排序规则为 utf8_general_ci 的test表:
    CREATE TABLE test (
    RESOURCE_ID bigint(20) NOT NULL COMMENT \'资源ID\',
    RESOURCE_NAME varchar(128) NOT NULL COMMENT \'资源名称\',
    CHANGED_TIME varchar(20) NOT NULL COMMENT \'数据变化时间(insert和update)\',
    TEACHER_NAME varchar(128) NOT NULL COMMENT \'老师名称\',
    STUDENT_NAME varchar(128) NOT NULL COMMENT \'学生名称\',
    UNIQUE KEY RESOURCE_ID (RESOURCE_ID,TEACHER_NAME,STUDENT_NAME)
    ) ENGINE=InnoDB DEFAULT CHARSET=UTF8 COLLATE=utf8_general_ci;

插入数据
INSERT INTO test (RESOURCE_ID, RESOURCE_NAME, CHANGED_TIME, TEACHER_NAME, STUDENT_NAME) VALUES(1, \'dd-dd\', \'2022-12-15 16:49:25\', \'dd\', \'zz\');
再次插入一个大写的 DD 老师名称
INSERT INTO test (RESOURCE_ID, RESOURCE_NAME, CHANGED_TIME, TEACHER_NAME, STUDENT_NAME) VALUES(1, \'dd-dd\', \'2022-12-15 16:49:25\', \'DD\', \'zz\');
此时就会提示报错,主键冲突,SQL 错误 [1062] [23000]: Duplicate entry \'1-DD-zz\' for key \'RESOURCE_ID\'
修改 TEACHER_NAME 的字段编码为 utf8_bin,执行sql: alter table test modify TEACHER_NAME varchar(128) collate utf8_bin not null COMMENT \'老师名称\';
再次执行插入sql:
INSERT INTO test (RESOURCE_ID, RESOURCE_NAME, CHANGED_TIME, TEACHER_NAME, STUDENT_NAME) VALUES(1, \'dd-dd\', \'2022-12-15 16:49:25\', \'DD\', \'zz\');
数据写入成功,结果如下:

mysql查询时不区分大小写

  一次偶然的机会,发现在登陆验证时,改变用户名的大小写,同样可以登录成功,这是由于,当时使用的mysql数据库对大小写不敏感,查询时总是能查询到数据。一番查找资料,给出的原因是:在创建数据库的时候,选择了utf8_general_ci排序规则。

  创建数据库时,需要同时选择字符集和排序规则,字符集大家都知道是怎么回事,那排序规则干嘛用的呢?

  排序规则:是指对指定字符集下不同字符的比较规则。其特征有以下几点:
    1、 两个不同的字符集不能有相同的排序规则
    2、 两个字符集有一个默认的排序规则
    3、 有一些常用的命名规则:如_ci结尾表示大小写不敏感(caseinsensitive),_cs表示大小写敏感(case sensitive),_bin表示二进制的比较(binary)。

  我用的是5.6版本的mysql,对于这个版本是不支持utf8的cs排序规则,如果要想对大小写敏感,可以使用_bin的排序规则。

  与此同时,可以使用“show COLLATION;”查询当前版本的数据库支持的所有排序规则。使用 “show charset like \'utf8%\';”进一步查看当前字符集的默认排序规则是什么。

  对于_ci的规则,表示不区分大小写,如图所示:

  对于使用_bin排序规则的查询如下:

   对于已经创建好的表,可以是用如下命令进行修改(修改表结构的Collation属性):

    ALTER TABLE TABLENAME MODIFY COLUMN COLUMNNAME VARCHAR(50) BINARY CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL;

    上面着重色部分分别表示表名和列名。

  

以上是关于mysql设置字段的排序规则对大小写敏感的主要内容,如果未能解决你的问题,请参考以下文章

怎样设置PostgreSQL中字段和表名对大小写敏感

mysql 解决数据库对大小写敏感的问题

mysql查询时不区分大小写

一个因MySQL大小写敏感导致的问题

MySQL大小写敏感

MySQL不区分大小写设置