最近在坛子里还看到说到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,自然没有这个问题。副作用是改变了原有数据长度,且涉及到重做表。

分享到:

2010-11-09 11:29

浏览 2527

论坛回复 / 浏览 (1 / 1706)

分类:数据库

评论

2 楼

nofreezou

2012-09-21

LZ要先说一下mysql什么版本,我在mysql5.1.54上测试是没有这个问题的

另外再请教一个问题,strings/ctype-gbk.c 里面gbk转unicode的编码不全,这个bug为啥没人提呢?  如 static uint16 tab_gbk_uni0[]的最后,很多都是0,但是真正的gbk编码后面的还是有值的 如过set names gbk,添加到一个utf8的表里面,这样的字符就丢失了

另外有空希望LZ再写些文章介绍下源代码相关的事~~比如里面很多奇怪的变量名、文件名

1 楼

babaoqi

2010-11-25

顶一个,学习一下!

没研究过这么深呢

mysql y_关于MySQL中Y和~问题相关推荐

  1. mysql''和null,mysql中NULL和null的区别

    接触php的web开发一段时间了,在进行数据库操作的时候经常会遇到一个问题,使得同一字段在页面显示时有3种类型NULL,null以及数字,当时的解决办法是将这一字段定义为varchar类型,在插入数据 ...

  2. mysql case break_按月转移日志表中日志时,mysql总是报‘MySQL server has gone away’这样的错!...

    我有一段清除数据库日志的脚用来按月清除数据库中的日志文件然后再把它们按月分表存储,脚本平时运行正常但是每到月初一定会报一次'MySQL server has gone away'这样的错,不知道为什么 ...

  3. centos编译apache php mysql,在CentOS6.7中编译安装 apache php mysql

    安装 开发工具 yum groupinstall "Development Tools" ------------------------------ tar -jxvf apr- ...

  4. linux系统 安装mysql,在linux系统中安装MySQL

    1.安装 Linux 系统中自带的 MySQL 安装包 在现在常用的发行版本里都集中了MySQL安装包 CentOS系统中的YUM中包含了MySQL安装包,版本是MySQL5,rpm软件包的名称是my ...

  5. centos mysql 安装教程_CentOS中安装MySQL步骤详解

    本文中Linux环境为CentOS 6.4 32位,且安装选择的是Basic Server版. 在有些Linux版本中会自带有MySQL数据库,所以在安装之前,需要检查当前Linux环境中是否已有My ...

  6. Linux CentOS 中安装 MySQL 与卸载 MySQL(三)

    VMware 安装 MySQL 内容 一.软件下载 二.安装步骤 1. 上传压缩文件 2. 防止依赖冲突 3. 安装依赖 4. 查找以前是否装有mysql 5. 查看安装包目录 6. 安装mysql- ...

  7. mysql添加user表中的用户

    mysql添加user表中的用户 默认情况下是不支持向user表中添加用户的,所以不建议使用 所以修改my.conf中的 sql-mode=STRICT_TRANS_TABLES,NO_AUTO_CR ...

  8. mysql获取时间部分_mysql中取日期的一部分

    DATE_FORMAT(date,format) 根据format字符串格式化date值.下列修饰符可以被用在format字符串中: %M 月名字(January--December) %W 星期名字 ...

  9. mysql如何在if中设置return_mysql 存储过程 if return

    MySql存储过程 MySQL 存储过程是从 MySQL 5.0 开始增加的新功能.存储过程的优点有一箩筐.不过最主要的还是执行效率和SQL 代码封装.特别是 SQL 代码封装功能,如果没有存储过程, ...

最新文章

  1. 【分块】#6281. 数列分块入门 5(区间开方,区间求和)
  2. python代码需要背吗-20个Python代码段,你需要立刻学会,好用到哭!
  3. 共享内存简介和mmap 函数
  4. C#教程6:流控制语句
  5. 北京内推 | 微软亚洲互联网工程院招聘NLP方向研究实习生(可远程)
  6. WKQ学习(后台知识)
  7. java数组末尾添加元素_JavaScript 数组 Array对象增加和删除 元素
  8. C基础06天--字符串
  9. LeetCode 889. Construct Binary Tree from Preorder and Postorder Traversal
  10. C++类的继承与派生
  11. Linux操作系统中sed工具常见用法
  12. Security+ 学习笔记16 密钥管理
  13. 零基础学python电子书-零基础学Python(全彩版)
  14. python提取停用词_python文本处理 数据挖掘 停用词检索
  15. postman下载文件
  16. javaSE(完整版)
  17. 微软开始彻底封杀IE浏览器
  18. 【华为机试029】合唱队
  19. [字符串题-java实现]20. 有效的括号
  20. 用python 写hadoop 需要怎么配置环境 python开发hadoop教程

热门文章

  1. 为Eclipse安装功能扩展插件
  2. jQuery API 3.1.0 速查表-打印版
  3. mysql颠覆实战笔记(五)--商品系统设计(二):定时更新商品总点击量
  4. ::before 和 ::after 伪元素用法
  5. 深入浅出asterisk(一):asterisk通道(Channels)
  6. 为什么大部分的婚姻都是凑合?数据告诉你真相
  7. 一图梳理企业数据治理的8项举措
  8. 区块链究竟是什么?看完这篇秒懂!
  9. mysql的这几个坑你踩过没?真是防不胜防
  10. 资深架构专家聊架构之道:规划、简化和演化(续)