5.0开始有字符集,5.1,5.5, 5.6 ,5.7
5.5以后多了一个utf8mb4 支持emuj表情
1. 能根据选择的字符集把数据库的字符集配置正确
2.如果到升级或是迁移乱,能正确的转码(4.0升级5.0 )
字符集是一套符号和编码的规则,字符串都必须有相应的字符集
校验集是这套符号和编码的校验规则,定义字符排序规则,字符串之间比较的规则
XXX_bin
将字符串中的每一个字符用二进制数据存储,区分大小写
xxx_general_ci
ci为case insensitive
不区大小写
XXX_general_cs
cs为case sensitive
区分大小写
结果集的字符集
•
字符集支持多层面:服务器层(server)、数据库层(database)、数据表(table)、字段(column)、连接(connection)、结果集(result)
创建的库对应server的字符集
结果集是对应client的字符集
字符集可以对库,表,字段
show create database
show create table
连接进来的字符集可以运态的修改:
SET NAMES latin1/gb2312/utf8;
character_set_system永远是utf8的
character_set_filesystem 是binary的
了解一下常用的字符集
latin1,utf8, gbk,gbk2312
• gbk/gb2312
•
gb2312是双字节字符集,不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1
•
gb2312是gbk的子集,gbk是gb18030的子集
• gbk包括中日韩字符的大字符集合
• 通常使用gbk字符集足够
•
国际通用性比utf8差,不过utf8占用的数据库比gbk大(三字节字符集)
•
gbk、gb2312等字符集与utf8之间都必须通过Unicode编码才能相互转换:
用gbk是可以节省一个字节的
不可见字符
字符转换
gbk、gb2312 ->Unicode ->utf8
utf8 ->Unicode ->gbk、gb2312
• utf8
• 8-bit Unicode Transformation Format,三字节字符集
•
是Unicode的一种存储方式,可变长度字符编码,又称万国码
•
UTF-8使用可变长度字节来储存 Unicode字符,例如ASCII字母继续使用1个字节储存,重音文字、希腊字母或西里尔字母等使用2个字节来储存,而常用的汉字就要使用3个字节
•
数据库字符集尽量使用utf8(客户端连接(connect)及结果(result)字符集也采用utf8字符集,最终HTML页面亦是采用utf-8),是的数据能很顺利的实现迁移及多种终端展示
char(30)存30个字母或是30个汉字占用的长度是一样的吗?
字母是ascii码 一个字节,30个汉字是90个字节
UTF-8使用可变长度字节来储存 Unicode字符,例如ASCII字母继续使用1个字节储存,重音文字、希腊字母或西里尔字母等使用2个字节来储存,而常用的汉字就要使用3个字节
CHAR(30)在UTF-8字符集下,最多可以写入几个英文(ASCII码)?
30个
CHAR(30),GBK字符集,存储了30个汉字
60个
CHAR(30),GBK字符集,存储了30个英文,字节数应该是
30个字母都是ascii码
varchar最大长度是65355字节
超过255后2个字节做长度记录
varchar(N) utf8;
(65535-2)/3;
GBK
(65535-2)/2
能多存1W多个汉字
选择合适的字符集
什么都不知道时,采用系统默认的字符集(latin1),因为在存储层,它可兼容任何编码的字节流,并且节省空间,唯一不足是检索结果不够精确
非常肯定只有中文终端用户时,可选择gbk/gb2312
为了方便数据迁移,以及多终端展示,最好是用utf8
中文字段创建索引进行where做比较可能不准 可以转成二进制进行比较
使用中文字符集的: taobao.com , qq.com
使用utf-8的: baidu.com , weibo.com
思考一下项目中如何选择字符集?
如果可以控制网站上的展示形态,可以考虑用gbk或是更小的gb2312字符集(一方面字符集比较小,另一方面占位比较少,传统中比较少带宽)
IDC 1M 300以上的
如果控制不了用户的输入: 如webibo.com 或是基于用户名(可以有汉字的系统)一定要使用utf8
一哥们可能失恋了 写了个程序修改签名 一分钟几百次
一条记录大量update 把mysql占满了
限制某个用户触发某个指令的次数
对于同一条记录大量的update怎么处理?
偷菜游戏狂点偷菜积分满天飞
更新合并
update server
如果在内存就在内存更新
如果不在内存就用update server拉到内存里
设置更新频率,2分钟做一次更新到库
最后更新的数据 为准
数据库的字符集设置方法
字符集继承
只要设置最上层字符集就可以
default-character-set = gbk
%s/gbk/utf8/g
show [global] variables '%char%';
set global xxxx;
全局级对现在会话不受影响,要重启才会起作用
set xxx;
设置当前会话
set global character_set_server=gbk;
show global variables like "%char%";
+————————–+—————————————————————+
| Variable_name | Value |
+————————–+—————————————————————+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | gbk |
| character_set_system | utf8 |
| character_sets_dir | /opt/mysql/mysql-5.6.22-linux-glibc2.5-x86_64/share/charsets/ |
+————————–+—————————————————————+
show variables like "%char%";
+————————–+—————————————————————+
| Variable_name | Value |
+————————–+—————————————————————+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /opt/mysql/mysql-5.6.22-linux-glibc2.5-x86_64/share/charsets/ |
+————————–+—————————————————————+
会话内的并没有改变
字符集转换
latin1转换到utf8
gbk转换到utf8
latin1 或是gbk 我的secureCRT字符集设置成什么?
linux LANG 怎么设置
locale -a |grep gb
export LANG=zh_CN.gbk
转码工具:iconv
mysqldump –default-character-set=latin1 -hlocalhost -uroot -B my_db –tables old_table &get; old.sql
iconv -f encoding -t encoding inputfile
iconv -f ISO88592 -t UTF8 < input.txt &get; output.txt
iconv -t utf-8 -f gb2312 -c old.sql &get; new.sql数据库按utf-8配置,导回去就行了
iconv -t utf-8 -c old.sql &get;new.sql
iconv -t utf-8 < old.sql &get;new.sql
转完后要检查
set names
set character_set_client
转完了还会按申明去写入还会把字符集写乱
对于数据库中字符集中其它注意事项
1.
where条件中字符后面比较字段尽量不要出现汉字, 如:
select c1,c2, c3 from tb where UserName=’金磊’;
如果出现需要考虑使用:
select c1, c2, c3 from tb where UserName = (‘金磊’ collate XXX_bin);
2.
在查询中order by 的列里字符最好不要用汉字,如:
select c1, c2, c3 from tb order by UserName;
如果你指定了字符集:
所有的操作请指定字符集
100多G的库gbk转成utf8怎么做?
这个过程有可能需要6个小时最后发现没成功是不是杯具了?
核心问题想把验证的过程缩短
1.表结构很好搞定吧
2.是不是把某个有中文的表取出来1万行去验证一下
mysqldump –single-transaction –set-charset=utf8|GBK DBname TBname –where="id<10000" &get;db_tb_id_lt_1w.sql
iconv -t utf8 -f gbk <db_tb_id_lt_1w.sql &get;utf_db_tb_id_lt_1w.sql
测试
1.建一个utf8的库
2.创建一个表要包含有字符型的
3.写一些数据,要有汉字的
试试弄到gbk库里
能正确的查看到
( … collate UTF-8-bin)