日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql校对规则_MYSQL校对规则

發(fā)布時間:2023/12/19 数据库 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql校对规则_MYSQL校对规则 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、前言

有時候遇到這種情況,你用一個like語句查詢,查到的結(jié)果中有一些并沒有包含你查詢的關(guān)鍵詞的紀(jì)錄;

有時候遇到這種情況,你的數(shù)據(jù)庫自作聰明的大小寫不敏感,讓你在更新時把大小寫不同的兩條記錄都更新了;

有時候遇到這種情況,你的查詢語句一切正常,查詢卻失敗了,報(bào)告Illegal mix of collations錯誤;

你很困惑,在想數(shù)據(jù)庫是不是壞了。。。其實(shí) ,這些都和數(shù)據(jù)庫字符集的校對規(guī)則有關(guān);了解了校對規(guī)則,你就知道怎樣處理這些問題。

那么,校對規(guī)則是怎么回事呢?它是一組規(guī)則,負(fù)責(zé)決定某一字符集下的字符進(jìn)行比較和排序的結(jié)果。

比如說,有l(wèi)atin1字符集中的字母A和a,我們需要它們在比較的時候相等,那么,我們可以使用字符集校對規(guī)則 latin1_general_ci;這種校對規(guī)則在比較和排序的時候不區(qū)分大小寫;如果我們需要他們在比較的時候不等呢?也很簡單,我們可以使用字符集校對規(guī)則latin1_bin;這種校對規(guī)則會以二進(jìn)制的方式對字符進(jìn)行比較,很明顯,a和A的二進(jìn)制編碼不同,比較的結(jié)果就是不等。

上面的場景說明了校對規(guī)則在最簡單情況下起的作用;實(shí)際情況與此并沒有太多不同,只不過稍微有些復(fù)雜而已。

二、校對規(guī)則總覽

我們可以使用SHOW COLLATION 指令來查看數(shù)據(jù)庫支持的校對規(guī)則

在圖中,我們列出了數(shù)據(jù)庫支持的latin1字符集的校對規(guī)則。為什么一種字符集竟然有這么多種的校對規(guī)則呢?因?yàn)樵诓煌那闆r下,對比較的結(jié)果有不同的期待,所以就有了不同的校對規(guī)則。前面說的大小寫敏感(latin1_general_cs)和不敏感(latin1_general_ci)是兩種校對規(guī)則,根據(jù)二進(jìn)制方式進(jìn)行比較(latin1_bin)也是一種校對規(guī)則,德國人(latin1_german1_ci)和西班牙人(latin1_spanish_ci)使用的某些不同的拉丁字符在某些情況下是等價(jià)的,所以有了兩種新的校對規(guī)則。

舉個例子,在latin1_german1_ci中,如下字符是等價(jià)的,而他們,具有不同的外形和編碼。當(dāng)然,它們的編碼不同,所以在latin1_bin校對規(guī)則下,他們又是不等價(jià)的了。

A,a,à,á,?,?,?,?,?,à,á,a,?,?,?,?

三、校對規(guī)則導(dǎo)致的問題

1、混合校對規(guī)則比較

兩個字符串比較,要求兩者必須有相同的校對規(guī)則,或者兩者的校對規(guī)則是相容的——所謂相容是指,兩種校對規(guī)則優(yōu)先級不同,比較的時候兩者使用高優(yōu)先級的校對規(guī)則進(jìn)行比較,比如latin1_bin的優(yōu)先級相對較高。

CREATE TABLE `tbl` (

`col_a` int(11) default NULL,

`col_b` char(20) character set latin1 collate latin1_general_ci default NULL,

`col_c` char(20) character set latin1 collate latin1_german1_ci default NULL,

`col_d` char(20) character set latin1 collate latin1_bin default NULL,

KEY `col_a` (`col_a`),

KEY `col_b` (`col_b`)

) ENGINE=MyISAM DEFAULT CHARSET=latin1

在這個表中,col_b、col_c、col_d的校對規(guī)則各不同;其中,latin1_general_ci和latin1_german1_ci 校對規(guī)則同級,不能進(jìn)行比較;如果強(qiáng)行比較的話,就會報(bào)錯,如下:

mysql> select * from tbl where col_b = col_c;

ERROR 1267 (HY000): Illegal mix of collations (latin1_general_ci,IMPLICIT) and (latin1_german1_ci,IMPLICIT) for operation '='

而latin1_general_ci和latin1_bin的優(yōu)先級不同,latin1_bin高于latin1_general,因此比較的時候,會按照latin1_bin的規(guī)則進(jìn)行比較。

mysql> select * from tbl where binary col_b = col_d;

Empty set (0.00 sec)

當(dāng)然,可以在sql語句中強(qiáng)制指定校對規(guī)則進(jìn)行比較,下面這個例子就說明了這一點(diǎn):

mysql> select * from tbl where col_b COLLATE latin1_danish_ci = col_c COLLATE latin1_danish_ci;

Empty set (0.00 sec)

2、校對規(guī)則導(dǎo)致的問題——SELECT出錯誤的記錄

在上面的基礎(chǔ)上,我們要演示一個常見的問題;我們需要對該數(shù)據(jù)表進(jìn)行一定的處理:

alter table tbl modify col_b collate latin1_swedish_ci default null;

insert into tbl (col_b) values ('hao123');

然后進(jìn)行下面的查詢

我們希望查詢的是包含“劉”的記錄,hao123這個和“劉”沒有任何關(guān)系的條目被選了出來,看起來很奇怪。

不過這不是數(shù)據(jù)庫出了問題,而是校對規(guī)則的使用上存在問題:

下面是我們使用ultraedit察看字符串的二進(jìn)制編碼的結(jié)果,在gbk編碼下,hao123的編碼為68 61 6f 31 32 33,而劉的編碼位C1 F5。

在前面的latin1_swedish_ci 校對規(guī)則中可以看到:

61和C1都與41等價(jià)

6F和F5都與4F等價(jià)

這就是ao = 劉的原因。

解決辦法有兩個:

1)修改該字段的字符集和校對規(guī)則,改成gbk,這該問題不在存在。這是完美的解決方案,不過有些時候你沒有權(quán)限對數(shù)據(jù)庫進(jìn)行這樣的改動。

mysql> alter table tbl modify col_b char(20) charset gbk default null;

Query OK, 1 row affected (0.01 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> select * from tbl where binary col_b like like '%劉%';

Empty set (0.00 sec)

2)查詢的時候聲明校對規(guī)則為latin1_bin 。這樣可以在一定程度上緩解這個問題;不過如果col_b中只要含有c1 f5,就會被選出來——而c1 f5可能恰好是另外兩個字符的前半截和后半截,或者干脆就是 á ? ....

mysql> select * from tbl where binary col_b like '%劉%';

Empty set (0.00 sec)

轉(zhuǎn)載:http://hi.baidu.com/cuttinger/item/e23013e372ee62adce2d4fda

總結(jié)

以上是生活随笔為你收集整理的mysql校对规则_MYSQL校对规则的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。