当前位置:Gxlcms > 数据库问题 > centos mysql 实战 第六节课 字符集

centos mysql 实战 第六节课 字符集

时间:2021-07-01 10:21:17 帮助过:3人阅读

centos mysql 实战 第六节课    字符集

 

 

一定要研究清楚mysql安装脚本


字符集

乱码
数据迁移
1. 理解字符集怎么会事
2. 不同的字符集进行转换


什么是字符集
gbk , utf8
gb2312
latin1
一套符号编码规则
字符串都必须有相应的字符集,除了二进制没有字符集

校验字符集的概念
流式传输

多字节
latin1 单字节
gbk 2字节
utf8 3字节
校验字符集的概念, 字为单位
归类的方法,就是3类
xxx_bin 以二进制形式存储区分大小写

SHOW CHARACTER SET ;查看mysql支持哪些字符集

XXX_general_ci :默认的字符集 case insensitive 不区分大小写 等于比较的时候不区分大小写,而存储的时候是区分大小写


xxx_general_cs :case sensitive

每个字符集都会有_general_cs/ci 结尾来区分大小写
而binnary 类型字符集不会区分大小写

 

操作系统有没有字符集
终端里面
cat /etc/sysconfig/i18n 配置文件,服务器的字符集

技术分享
echo $LANG
locale -a 查看当前系统所支持的字符集
SecureCRT 终端有没有字符集,菜单项:终端-》外观-》窗口,选择Courier New


三码统一
服务器,终端, DB级别
db server -> dbname -> table -> column
物理属性的字符集
连接字符集
结果集字符集:结果集字符集继承自连接字符集

\s :mysql提示符下输入\s
set names utf8 ; 更改客户端字符集,连接字符集和结果集字符集,只影响客户端的属性

技术分享

技术分享

有时候更改了global字符集,但是当前会话还是显示原来的字符集,这个需要打开一个新的会话才能看到效果,原已经打开的session看不到效果,只影响新打开的session
show global variables like "%char%";
set global
show variables like

技术分享


set global 更改全局级的
set 没有Global 更改当前会话Session


继承
服务端:server => database => table => column
服务器层 命令行 本地会话和全局会话 (set xx是 local,set global xx是全局)
conn -> result

 


吴炳锡(82565387) 21:06:50
早期版本MySQL默认字符集都是latin1


常见的字符集有哪些呢
目前国内用得最多:gbk/gb2312 ,gb2312 包含于gbk ,Gbk 是 gb18030 的子集,gbk 包含中日韩 通杀亚洲语言
utf8 utf8mb4


不同字符集的转换
unicode
gbk -> unicode -> utf8


吴炳锡(82565387) 21:15:18
utf8 是unicode的变形
三字节的字符集,可变长度,万国码
不同字符长度按照实际长度存储而不是固定存储,所以跟varchar差不多
用utf8存储字符
如果字符是ASCII utf8  1个字节来存储的
如果字符是双字节 utf8 还是2个字节来存储
如果字符是汉字 utf8 三个字节的
Tips提示
db: utf8
前端网站 也采用utf8


ASCII码
1字节 ,但实际占用: 7bit
latin1 8bit 1字节


存储长度

char(30) char(M) M不论是哪个版本mysql都是指字符数
30 是字符个数,字节呢?
latin1 char(30)
set names gbk;
只能写进去15个汉字
建表时字符集和存进去的字符集一定要一致


char(30)
utf-8
吴炳锡(82565387) 21:27:01
CREATE TABLE `t1` (
`i1` char(30) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8
insert into t1(i1) values(repeat(‘吴‘,10));
(product)root@localhost [wubx]> insert into t1(i1) values(repeat(‘吴‘,30)); 没有报错,能存进去,但是实际存储长度是90字节
如果insert的是gbk,则会报错
char:30*3 =90 Byte
varchar(30) :30*3 +1=91 Byte ,varchar 255byte
char(30) utf8 :如果英文字母 30个字母 30*1=30字节


GBK 双字节
char(30) gbk :30个字符 60个字节
varchar(30) gbk :30个字符 61个字节

 

char(30) latin1 一个字节一个字符
汉字需要2个字节
gbk存进去latin1 15个汉字 15*2 = 30 字节
utf8存进去latin1 10个汉字 10*3 = 30 字节

 


看看国内大厂都在用什么字符集
看国内大厂都在用什么字符集
www.taobao.com
右键,查看源文件


总结一下
有用户输入的地方:utf8
手机类设备
移动类设备
emoji:utf8mb4


腾讯或新闻类网站使用gbk gbk2312
人家对自已的内容心里很有底
gbk 和 utf8比有啥优劣势
gbk优势:省空间和网络流量


项目里使用什么字符集
有用户输入的 : utf8 ,utf8mb4
信息类的,淘宝都使用图片商品描述,防止卖家使用乱七八糟的字符: gb2312 ,gbk


吴炳锡(82565387) 21:54:16
nginx, apache一定要开压缩
httpwatch :查看http header 是否已经压缩

 


字符集配置
只需要改两个地方
1、my.cnf中的服务器端配置charset-set-server
2、第三方终端xshell中指定utf8

 

 


字符集转换
latin1 -> utf8
gbk -> utf8
latin1 -> gbk
utf8 -> gbk 有可能会遇到字符的丢失

字符集的转换,Linux下推荐iconv这个工具 , iconv --help
which iconv
/usr/bin/iconv

技术分享

技术分享


file filename
file 2.txt
2.txt: ASCII text
file 2.txt
2.txt: UTF-8 Unicode text
cat 2.txt
1468 84.94.214.212.ca
sdf误操


只有存在中文的时间才需要转码
当前的字符集下,你看到的字符是能正确显示的,导过去也能正确显示就OK
gbk-> utf8
mysqldump --default-character-set=gbk


iconv -l
-c :不理会不认识的字符
如果不知道源文件的字符集,那么可以不用理会,只使用to-code-name -t utf8
iconv -t utf8 -c xxxx.sql >xxx_utf8.sql
如果iconv没有报错那就是对的

 


Tips
300G DB从GBK转成UTF8(编码转换,不管转成什么,都有可能会有问题的。这是MySQL最坑的地方,不管超集转子集还是子集转超集)
mysqldump 3个小时
转一下码 大概1个小时
吴炳锡(82565387) 22:19:44
mysql < 7-9个小时
我操没倒对还是乱码

 


在遇到转码的事情时
首先把表结构导出来,导出来是utf8 的表结构
再mysqldump 导出1000行数据进行测试
mysqldump 支持where
mysqldump --where="1=1 limit 1000" ,因为不能where limit 1000
测试通过了,能得到一个正确的方法了
然后在处理来那个300G的文件
3个小时导出来
1个小时转码
screen -S "time mysql<xxx.sql"
下班回家

把出错的成本降低一点

 

注意:主从编码一定要一致!!!!!!!!


==========
怎么避免乱码
1. 三码统一
服务器端,终端的, DB级的, 程序级别(sqlyog)
2. 真的遇到乱码
想想我们做过什么
环境发生了什么变换

转码操作是需要停库的

导出工具:mydumper ,mysqlpump

 

误操作一定不要重启系统
吴炳锡(82565387) 21:59:45
chown -R mysql:mysql /usr
吴炳锡(82565387) 21:59:55
reboot
吴炳锡(82565387) 22:00:02
系统起不来了

 

mysql Crashed
/etc/init.d/mysqld
recovery :mysqld timeout 只能死等,等日志要么成功,要么失败
不停kill mysql,数据页损坏
卡在99%的话
A180-周创-广州<jessewzc@vip.qq.com> 22:04:34
有进度条。。他Kill。。。额。。。
吴炳锡(82565387) 22:04:37
就是等,等几个小时都要

 

==============================

MySQL运行中被改权限测试
http://wubx.net/mysql-running-change-owner/
今天一个接到一个朋友求助,说是数据在运行中,数据库的目录被改了权限。如: 数据库目结构如下:


datadir=/data/mysql/mysql3306/data
log-bin = /data/mysql/mysql3306/logs
tmpdir = /data/mysql/mysql3306/tmp
1
2
3
datadir=/data/mysql/mysql3306/data
log-bin = /data/mysql/mysql3306/logs
tmpdir = /data/mysql/mysql3306/tmp
被运维同步执行了:


chown -R root:root /data/mysql/mysql3306
1
chown -R root:root /data/mysql/mysql3306
1.构建主从环境


mysql;3306 主
/data/mysql/mysql3306/{data,tmp,logs}
mysql;3307 从
/data/mysql/mysql3307/{data,tmp,logs}
1
2
3
4
mysql;3306 主
/data/mysql/mysql3306/{data,tmp,logs}
mysql;3307 从
/data/mysql/mysql3307/{data,tmp,logs}
2. 在主的wubx库里创建:


CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
)
1
2
3
4
5
CREATE TABLE `t2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) DEFAULT NULL,
PRIMARY KEY (`id`)
)
确认复制正常。

3. 把主库的目录权限改成root


chown -R root:root /data/mysql/mysql3306
1
chown -R root:root /data/mysql/mysql3306
4. 弄出来大量的写入


for i in `seq(100000); do mysql wubx -e "insert into t2(name) vlaues(‘golang$i‘)"; done
1
for i in `seq(100000); do mysql wubx -e "insert into t2(name) vlaues(‘golang$i‘)"; done
5. 观查主库和从库上数据
发现日志没有切换时,数据都可以写入,同步正常。 主库上binlog还可以正常写入。

6. 模拟日拟切换
主库上执行: flush logs;
得到报错:
切换日志错误

从库同步报错:
1595错误
show slave status\G;
show slave status\G;

从这里看出来,从库获取到主库日志切换指令,但主库没能创建出来新的日志,所以造成复制中断。

7.结论
主库上不影响数据写入,但发生日志切换后,不能进行新的日志写入,但没卡住写入。
从库上在主库日志发生切后,能得到新的日志文件名,但不能获到新的日志,所以同步停掉。

8.修复建议:
通过实验说明,主库上的数据是最全的,在后续日志切换失败后,没有影响数据的写入。但数据没有同步到从上。

 

思考:

这个有点是mysqld的一个bug的感觉了,日志已经无法写入,但数据还可以写入。 很容易造成同步有问题。 对于数据不同步怎么修复。多次给学生们讲过,也能很快的把环境处理好。

Good luck!

=============================================
mysqldump 的Tips
http://wubx.net/mysqldump-的tips/
只导出表结构:
mysqldump -d –trigger=false
只导出存储过程:
mysqldump -f -Rtdn –triggers=false
只导出触发器:
mysqldump -f -tdn –triggers
只导出事件:
mysqldump -f -Etdn –triggers=false
只导出数据:
mysqldump -f –single-transaction –triggers=false -t

 

f

centos mysql 实战 第六节课 字符集

标签:

人气教程排行