锁定老帖子 主题:关于MySQL中Y和~问题
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|||
---|---|---|---|
作者 | 正文 | ||
发表时间:2010-11-09
最后修改:2010-11-09
最近在坛子里还看到说到Y和~的问题,不知道mysql官方的bugs里面安排到什么时候解决这个bug。这里描述一下,说明一下原因。
1、 问题描述
上面的语句和显示结果容易看出,where c=’Y’的条件匹配到了 ‘~’.
2、 源码修改 打开strings/ctype-gbk.c,查看sort_order_gbk这个结构体,这里是gbk的码表。可以看到第157行为” 'X', 'Y', 'Z', '{', '|', '}', 'Y', '\177',”. 这里第二个’Y’明显错误, 将其改为’~’,重新编译,执行新的mysqld, 上述最后一个语句结果为
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,自然没有这个问题。副作用是改变了原有数据长度,且涉及到重做表。
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|||
返回顶楼 | |||
发表时间:2010-11-25
顶一个,学习一下!
没研究过这么深呢 |
|||
返回顶楼 | |||
浏览 1904 次