MySQL collation方法收集

2021-08-11 02:07:20 字數 4505 閱讀 2451

收集1:

問題是這樣的: 

一張test的表,字符集採用的latin1。 

select to_id from test where to_id='cn象_王'; 

+---------------+ 

| to_id | 

+---------------+ 

| cn陶_陶 | 

| cn象_王 | 

+---------------+ 

2 rows in set (0.00 sec) 

取cn象_王的資料,居然把cn陶_陶的資料也取回來了。 

這顯然是不允許的。 

檢視它們的編碼: 

(root@im_offlog1a)[test]> select hex('cn陶_陶'); 

+----------------+ 

| hex('cn陶_陶') | 

+----------------+ 

| 636eccd55fccd5 | 

+----------------+ 

1 row in set (0.00 sec) 

(root@im_offlog1a)[test]> select hex('cn象_王'); 

+----------------+ 

| hex('cn象_王') | 

+----------------+ 

| 636ecff35fcdf5 | 

+----------------+ 

1 row in set (0.00 sec) 

編碼的確是不一樣的,但是為什麼mysql會認為這兩條記錄是一樣的呢? 

一開始我們就把問題定位於collation引起的問題。 

show variables檢視 

| collation_connection | latin1_swedish_ci 

| collation_database | latin1_swedish_ci 

| collation_server | latin1_swedish_ci 

手工把這些引數修改為latin1_bin,結果居然一樣。這下感覺真是奇怪了。 

這裡先解釋一下mysql collation的命名規則: 

它們以其相關的字符集名開始,通常包括乙個語言名,並且以_ci(大小寫不敏感)、_cs(大小寫敏感)或_bin(二元)結束 

比如latin1字符集有以下幾種校正規則: 

校對規則 含義 

latin1_german1_ci 德國din-1 

latin1_swedish_ci 瑞典/芬蘭 

latin1_danish_ci 丹麥/挪威 

latin1_german2_ci 德國 din-2 

latin1_bin 符合latin1編碼的二進位制 

latin1_general_ci 多種語言(西歐) 

latin1_general_cs 多種語言(西歐iso),大小寫敏感 

latin1_spanish_ci 現代西班牙 

最後我們將**重建,手工指定**級別的collation為latin1_bin。 

這個問題就得到了解決。 

那麼問題又來了,為什麼我前面手工測試latin1_bin時不生效呢? 

原來mysql按照下面的方式選擇表字符集和 校對規則: 

如果指定了character set x和collate y,那麼採用character set x和collate y。 

如果指定了character set x而沒有指定collate y,那麼採用character set x和character set x的預設校對規則。 

否則,採用伺服器字符集和伺服器校對規則。 

而我們在建表的時候指定了character set,所以它永遠是採用對應的預設的校對規則。 

當然我們其實也沒必要重建**,只需要alter table db_allot convert to character set latin1 collate latin1_bin這樣轉換即可。 

另外建議collation都盡量採用字符集相應的bin型別的校對規則,這樣不容易出錯。

收集2:

show create table 

comment_content_1_01;

當當前表結構是下面這樣時:

create table `comment_content_1_01` (

`content_id` int(11) not null auto_increment,

`thread` varchar(50) default null,

`uname` varchar(100) default null,

`nick` varchar(100) default null,

`uid` int(11) unsigned default null,

`content` text,

`post_time` datetime default null,

`post_ip` int(10) unsigned default null,

`status` enum('unaudit','normal','deleted') not null default 'unaudit',

primary key (`content_id`)

) engine=myisam default charset=latin1

只修改一列的校驗規則可以用:

alter table `comment_content_1_01` change `thread` `thread` varchar( 50 ) collate latin1_bin default null;

表變為create table `comment_content_1_01` (

`content_id` int(11) not null auto_increment,

`thread` varchar(50) character set latin1 collate latin1_bin default null,

`uname` varchar(100) default null,

`nick` varchar(100) default null,

`uid` int(11) unsigned default null,

`content` text,

`post_time` datetime default null,

`post_ip` int(10) unsigned default null,

`status` enum('unaudit','normal','deleted') not null default 'unaudit',

primary key (`content_id`)

) engine=myisam default charset=latin1

修改表中所有字元列為指定校驗規則可以用:

alter table `comment_content_1_01` convert to character set latin1 collate latin1_bin

; 表結構變為:

create table `comment_content_1_01` (

`content_id` int(11) not null auto_increment,

`thread` varchar(50) collate latin1_bin default null,

`uname` varchar(100) collate latin1_bin default null,

`nick` varchar(100) collate latin1_bin default null,

`uid` int(11) unsigned default null,

`content` text collate latin1_bin,

`post_time` datetime default null,

`post_ip` int(10) unsigned default null,

`status` enum('unaudit','normal','deleted') collate latin1_bin not null default 'unaudit',

primary key (`content_id`)

) engine=myisam default charset=latin1 collate=latin1_bin

可是當此時執行:

alter table `comment_content_1_01` change `thread` `thread` varchar( 50 ) default null;

是沒有用的,因為不設校驗collate,就會按表指定的設定。

可以採用先把錶改為沒有collate的,

alter table `comment_content_1_01` convert to character set latin1;

然後整個表就都不帶collate,之後逐個加入需要collate的列。

關於springCloud中服務方呼叫方的配置

1.我方是服務方,別人呼叫我方,由我方提供位址,不需要呼叫feign。那麼,位址資訊在resourceconfig裡面做配置,resourceconfig中配置的位址相當於是把請求位址暴露給對方,並在此位址請求時對他放行。configuration enableresourceserver publ...

Container DataItem幾種方式

在繫結資料時經常會用到這個句程式 databinder.eval container.dataitem,x 或者 databinder.eval container,dataitem.x 今天又學到一種,而且微軟也說這種方法的效率要比以上兩種高。datarowview container.datai...

Linux Carmer driver註冊方法

最近又開始看carmer的驅動了,在linux下通常實用video4linux框架來實現video capture camera capture等功能,先說一下裝置註冊部分,ov7670.c中,註冊方法如下 static struct v4l2 i2c driver data v4l2 i2c da...