mysql y_关于MySQL中Y和~问题
最近在壇子里還看到說到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的碼表??梢钥吹降?57行為”'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和~问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 计算机技术在农机上的应用,计算机视觉技术
- 下一篇: linux cmake编译源码,linu