最近在坛子里还看到说到Y和~的问题,不知道mysql官方的bugs里面安排到什么时候解决这个bug。这里描述一下,说明一下原因。
1、 问题描述
mysql> create table t (c char(32)) engine=innodb;
Query OK, 0 rows affected (0.01 sec)
mysql> insert into t values('Y');
Query OK, 1 row affected (0.02 sec)
mysql> insert into t values('~');
Query OK, 1 row affected (0.00 sec)
mysql> select * from t where c='Y';
+------+
| c |
+------+
| Y |
| ~ |
+------+
2 rows in set (0.00 sec)
|
上面的语句和显示结果容易看出,where c=’Y’的条件匹配到了 ‘~’.
2、 源码修改
打开strings/ctype-gbk.c,查看sort_order_gbk这个结构体,这里是gbk的码表。可以看到第157行为” 'X', 'Y', 'Z', '{', '|', '}', 'Y', '\177',”. 这里第二个’Y’明显错误, 将其改为’~’,重新编译,执行新的mysqld,
上述最后一个语句结果为
mysql> select *from t where c='Y';
+------+
| c |
+------+
| Y |
+------+
1 row in set (0.00 sec)
|
3、原因说明
我们来分析一下strings/ctype-gbk.c的这个函数my_strnncoll_gbk_internal。当使用gbk字符时,在作字符串匹配的时候,调用此函数。
int my_strnncoll_gbk_internal(const uchar **a_res, const uchar **b_res,
size_t length)
{
const uchar *a= *a_res, *b= *b_res;
uint a_char,b_char;
while (length--)
{
if ((length > 0) && isgbkcode(*a,*(a+1)) && isgbkcode(*b, *(b+1)))
{
a_char= gbkcode(*a,*(a+1));
b_char= gbkcode(*b,*(b+1));
if (a_char != b_char)
return ((int) gbksortorder((uint16) a_char) -
(int) gbksortorder((uint16) b_char));
a+= 2;
b+= 2;
length--;
}
else if (sort_order_gbk[*a++] != sort_order_gbk[*b++])
return ((int) sort_order_gbk[a[-1]] -
(int) sort_order_gbk[b[-1]]);
}
*a_res= a;
*b_res= b;
return 0;
}
第8行是作中文判断的,先忽略。在我们的例子中,走的是第19行的判断。
可以看到,在判断字符值是否相同时使用sort_order_gbk[*a++] != sort_order_gbk[*b++]。当我们的*a=’~’, *b=’Y’时,由于上面说到的157行的原因,被判定为值相同。
(作为辅助验证,如果有兴趣把第二个’Y’ 改成 ‘Z’,以后Z和~就相同了)。
4、 其他解决方法
如果不改源码,也有”解决方法”
1) 使用binary查询
使用binary查询后,整个字符串对照流程都与gbk无关,因此不会碰到这个bug。副作用是导致大小写敏感。
2) 换字符集
从strings/目录下的各个ctype-*.c看, 只有gbk和gb2312有这个问题,因此改成utf-8,自然没有这个问题。副作用是改变了原有数据长度,且涉及到重做表。
分享到:
相关推荐
查看目前系统中关于 mysql 存在可以升级和安装的安装包。 然后,可以使用以下命令安装 MySQL: yum -y install mysql-server mysql mysql-devel 解决依赖关系 在安装 MySQL 时,可能会出现依赖关系问题。可以...
MySQL是一个广泛使用的开源关系型数据库管理系统(RDBMS),它以其高效、稳定和易于管理的特点,在Web开发和其他数据存储应用中占有重要地位。这份中文手册是英文原版的翻译版本,虽然可能不包含最新的更新,但对于...
远程连接MySQL所遇到的问题以及解决问题方法 在 Linux 系统中,使用 YUM 命令安装 MySQL 后,需要进行一系列的配置以便能够远程连接 MySQL 数据库。以下是解决不能进行远程连接 MySQL 数据库的问题的方法,这些方法...
在Windows系统中,这个目录通常位于MySQL的安装路径下,例如"C:\ProgramData\MySQL\MySQL Server X.Y\Data",其中X.Y代表MySQL的版本号。在Linux系统中,数据目录可能位于"/var/lib/mysql"或用户指定的其他位置。 ...
MySQL集群(一台主机安装MariaDB与MySQL同时运行) 以下是在已安装MySQL的情况下,安装MariaDB的主要步骤. [root@mariadb-near-mysql ~]# cat /etc/issue CentOS release 6.2 (Final) [root@mariadb-near-...
在IT行业中,数据库管理和编程是不可或缺的部分,而MySQL作为一个广泛使用的开源关系型数据库管理系统,其与C++的结合使用能够实现高效的数据操作。本篇将详细介绍如何在C++项目中利用mysql++库来调用MySQL数据库,...
在 MySQL 中创建用户有两种方法:使用 CREATE USER 命令和使用 GRANT 命令。 使用 CREATE USER 命令 CREATE USER 命令用于创建新的 MySQL 账户。要使用 CREATE USER,您必须拥有 mysql 数据库的全局 CREATE USER ...
在Linux环境中,使用`yum`(Yellowdog Updater Modified)工具来安装和更新MySQL数据库是非常常见的做法。`yum`是Red Hat系列Linux发行版(包括CentOS、Fedora等)中的软件包管理器,它能够帮助用户轻松地安装、更新...
例如,`mysql-connector-java-5.x.y.jar` 适用于MySQL 5.x版本,`mysql-connector-java-8.x.y.jar` 适用于MySQL 8.x版本。不同的版本可能支持不同的功能和API,因此,选择与数据库服务器版本兼容的驱动至关重要,以...
- 如果在安装过程中遇到 `-bash:wget: command not found` 错误,说明系统尚未安装 wget 工具,可以通过 `yum -y install wget` 命令安装 wget。 - 检查本地是否已经安装了 MySQL,可以通过命令 `rpm -qa | grep ...
对于MySQL5.7的安装,需要四个RPM包:`mysql-community-common-5.7.x.y.rpm`、`mysql-community-libs-5.7.x.y.rpm`、`mysql-community-client-5.7.x.y.rpm`和`mysql-community-server-5.7.x.y.rpm`。这里的x.y代表...
在遇到“MySQL无法安装的解决方案”这个问题时,通常是因为在重装或升级MySQL过程中,旧的服务残留在系统中,导致新安装的MySQL无法创建...在问题排查过程中,了解MySQL的安装流程和系统服务管理知识是非常有帮助的。
在本文中,我们将详细介绍如何在 CentOS6.5 操作系统上安装 MySQL5.5.37。由于 MySQL 是一个非常流行的关系型数据库管理系统,因此了解如何安装和配置 MySQL 是非常重要的。 卸载旧版本 在安装 MySQL 之前,我们...
yum -y remove mysql-libs-5.1.52-1.el6_0.1.i686 卸载二: 输入: #rpm -qa | grep -i mysql 显示: MySQL-client-5.1.62-1.glibc23.i386 MySQL-server-5.1.62-1.glibc23.i386 卸载方法: #rpm -ev MySQL-client-...
在本文中,我们将详细探讨如何在龙蜥Anolis8操作系统上安装MySQL 5.7数据库。...在整个过程中,`mysql离线安装.txt`可能包含了更详细的步骤或者解决特定问题的提示,记得参考该文档以确保顺利完成安装。
3. MySQL Devel: 提供了开发所需的头文件和库文件,方便开发者在C/C++等语言中编写与MySQL交互的应用程序。 二、安装MySQL 5.6.29 在Linux系统中,安装MySQL 5.6.29 RPM包通常分为以下几个步骤: 1. 更新系统包...
本文将详细介绍如何在Linux(包括CentOS 6、CentOS 7、RHEL 6和RHEL 7)上安装MySQL的二进制资源包,同时也会提供解决安装过程中可能出现的问题的策略。 首先,我们需要理解Linux发行版的包管理器,如CentOS/RHEL中...
总的来说,MySQL中的int、char和varchar在性能上的差异并非显著到足以成为决定性因素。开发者应根据实际需求,如数据的类型、大小、预期的增长、是否需要索引以及对可读性和可维护性的要求,来综合考虑选择哪种数据...