文档章节

字符集和字符编码

i
 ivisit
发布于 2017/08/22 00:54
字数 961
阅读 5
收藏 0

字符集(character set)。字符集的工作是给每一个字符定义一个二进制编号(称作code point)。最初始的ASCII字符集只用了1个byte的低位7bits定义了127个字符,其中还包括了部分控制字符,可以说极端简化的。于是有了各种的字符集(都是兼容ASCII的),比如ISO-,中文世界的BIG-5,GB2312/GB18030,以及国际统一字符集UNICODE等。

比如GB2312用1个字节的编号(最高位bit为0)兼容ASCII,用2个字节的编号(最高位bit全是1)表示其他字符,14个有效位可表示1.6w+的中文字符。

比如Unicode用了2个字节,最多可表示65535个字符。还是图样!后来发现6w也不够,于是Unicode又做了扩展。原来的0x0000-0xFFFF编号不变,称作BMP。之外又定义了0x10000-0x1FFFF,0x20000-0x2FFFF,0x30000-0x3FFFF一直到0x100000-0x10FFFF的16组同样大小的Plane。一共17组,21位有效bit,大于100w的字符。

字符编码(character encoding)可以说是Unicode引入的问题。ASCII和GBK字符集,字符的编号是怎样规定,就怎样存储,不存在不一致的问题。对于文件内容99.999%不会超过ASCII字符集范围的美国,如果直接按Unicode的字符编号,统一2字节存储传输,那有一半是全0的高位byte;而面对扩展平面的字符(如emoji表情字符),2个字节又不够了,不能每个字统一存3或4字节吧。UTF-8/UTF-16等一系列方案出现了。“字符编码”的中文译名极易误解,“对字符进行编码”或者“每个字符的编码”。其实那是字符集的工作,字符编码只对字符集中的编号的存储、传输、书写格式做了规定。不同的方案对同一个编号有不同的表示。比如在UTF-8中3字节表示的字符,在UTF-16用2字节表示。

UTF-8用1字节(编码单位code unit)表示7位有效位,3字节表示16位有效位,4字节表示21位有效位。UTF-8的格式理论上最多可以用6字节表示31个有效位的,但在2003年的RFC3629规范中,限定了最多使用4字节。【1】

UTF-16用2字节表示BMP的编码,4字节表示16组扩展平面的编码。而4字节的高位2字节,和低位的2字节,都是在BMP中没有映射到字符的保留编号,这和GB2312处理ACSII兼容的方法倒是一致。UTF-16的编码格式会导致字节序的问题,这里不展开了。

最后说一个mysql存储emoji字符的问题。Mysql的默认字符集配置成UTF-8时,最多支持3字节的字符编码。在5.5.3之后支持的utf8mb4(most bytes 4),可以兼容4字节的Unicode,满足U+1F601-U+1F64F区段的emoji字符的存储需求。好消息是utf8mb4是utf8的超集,除了将编码改为utf8mb4外不需要做其他转换。

对于 CHAR 类型数据,utf8mb4 会比utf8多消耗更多一些空间(预留4bytes空间vs预留3bytes空间)。当然,按惯例用VARCHAR 取代 CHAR才是王道啊。

【1】当时Unicode和UCS两大字符集合流了,保留了Unicode的17组编码空间和UCS的字符范围,Unicode的21bits有效位用4字节足够表示,更多的字节数没必要继续存在。

© 著作权归作者所有

i
粉丝 0
博文 1
码字总数 961
作品 0
私信 提问

暂无文章

OSChina 周一乱弹 —— 年迈渔夫遭黑帮袭抢

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @tom_tdhzz :#今日歌曲推荐# 分享Elvis Presley的单曲《White Christmas》: 《White Christmas》- Elvis Presley 手机党少年们想听歌,请使劲...

小小编辑
今天
1K
16
CentOS7.6中安装使用fcitx框架

内容目录 一、为什么要使用fcitx?二、安装fcitx框架三、安装搜狗输入法 一、为什么要使用fcitx? Gnome3桌面自带的输入法框架为ibus,而在使用ibus时会时不时出现卡顿无法输入的现象。 搜狗和...

技术训练营
昨天
5
0
《Designing.Data-Intensive.Applications》笔记 四

第九章 一致性与共识 分布式系统最重要的的抽象之一是共识(consensus):让所有的节点对某件事达成一致。 最终一致性(eventual consistency)只提供较弱的保证,需要探索更高的一致性保证(stro...

丰田破产标志
昨天
8
0
docker 使用mysql

1, 进入容器 比如 myslq1 里面进行操作 docker exec -it mysql1 /bin/bash 2. 退出 容器 交互: exit 3. mysql 启动在容器里面,并且 可以本地连接mysql docker run --name mysql1 --env MY...

之渊
昨天
12
0
python数据结构

1、字符串及其方法(案例来自Python-100-Days) def main(): str1 = 'hello, world!' # 通过len函数计算字符串的长度 print(len(str1)) # 13 # 获得字符串首字母大写的...

huijue
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部