mysql字符集

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

区分大小写

blob.png

blob.png

结果集的字符集


字符集支持多层面:服务器层(server)、数据库层(database)、数据表(table)、字段(column)、连接(connection)、结果集(result)

创建的库对应server的字符集

结果集是对应client的字符集

字符集可以对库,表,字段

show create database 

show create table 

连接进来的字符集可以运态的修改:

SET NAMES latin1/gb2312/utf8;


blob.png

blob.png

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字符集设置成什么?

blob.png

linux LANG 怎么设置

locale -a |grep gb

blob.png

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)