收集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...