UTF-8简介
UTF-8(8-bit Unicode Transformation Format)是一种针对Unicode的可变长度字符编码,也是一种前缀码。它可以用来表示Unicode标准中的任何字符,且其编码中的第一个字节仍与ASCII兼容,这使得原来处理ASCII字符的软件无须或只须做少部分修改,即可继续使用。因此,它逐渐成为电子邮件、网页及其他存储或发送文字的应用中,优先采用的编码。
UTF-8使用一至四个字节为每个字符编码(2003年11月UTF-8被RFC 3629重新规范,只能使用原来Unicode定义的区域,U+0000到U+10FFFF,也就是说最多四个字节):
128个US-ASCII字符只需一个字节编码(Unicode范围由U+0000至U+007F)。
带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要两个字节编码(Unicode范围由U+0080至U+07FF)。
其他基本多文种平面(BMP, Basic Multilingual Plane)中的字符(这包含了大部分常用字,例如CJVK常用字字符集 —— Chinese, Japanese, Vietnam, Korean)使用三个字节编码(Unicode范围由U+0800至U+FFFF)。
其他使用极少的Unicode 辅助平面(Supplementary Multilingual Plane)的字符使用四字节编码(Unicode范围由U+10000至U+10FFFF,主要包括不常用的CJK字符, 数学符号, emoji表情等)。
utf-8编码方式
unicode code point table
参考与扩展:
* UTF-8 https://en.wikipedia.org/wiki/UTF-8, 中文版 https://zh.wikipedia.org/wiki/UTF-8*
* Plane_(Unicode) https://en.wikipedia.org/wiki/Plane_%28Unicode%29*
* CJK characters https://en.wikipedia.org/wiki/CJK_characters*
* Emoji https://en.wikipedia.org/wiki/Emoji*
UTF-8与Unicode的关系
utf8编码是unicode编码的一种实现,可以简单的理解为unicode编码定义一串数字来一一对应我们用到的字符,utf8定义了如何将unicode定义的这串数字保存到内存中。 另外需要强调的是utf8是一种变长的编码规范。
unicode 的范围 U+0000 - U+10FFFF。
参考与扩展
** Unicode https://en.wikipedia.org/wiki/Unicode*
Mysql中的 UTF-8、UTF8mb3, UTF8mb4
utf8mb4, MySQL在5.5.3之后增加了这个utf8mb4的编码,mb4就是most bytes 4的意思,专门用来兼容四字节的unicode字符。
mysql中的utf8,就是最大3字节的unicode字符,也就是mysql中的utf8mb3.
参考
mysql-charset-unicode-utf8mb3 https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb3.html and https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8.html*
mysql-charset-unicode-utf8mb4 https://dev.mysql.com/doc/refman/5.5/en/charset-unicode-utf8mb4.html*
表示范围:
说明 | mysql utf8 / utf8mb3 | mysql utf8mb4 |
---|---|---|
max bit | 3 | 4 |
范围 | 基本多文种平面 + US-ASCII | 辅助平面(Supplementary) + 基本多文种平面 + US-ASCII |
unicode范围 | U+0000 - U+FFFF | U+0000 - U+10FFFFF |
常见字符 | 英文字母,CJK大部分常用字等 | CJK非常用字,数学符号,emoji表情等 |
那么问题来了,如果用了utf8mb3编码的mysql数据库,在插入一些4字节长的字符时就会报错(形如:"java.sql.SQLException: Incorrect string value: '\xF0\x9F\x94\x91\xE6\x9D...' for column 'core_data' at row 1" 的错误),后文会介绍如何在Java中过滤掉这些字符。
要在Java中过滤Mysql的utf8mb4,必须弄清Java是如何支持Unicode编码,接下来徐徐展开......
编码简介
下面先介绍几个概念:character(字符), character set(字符集), coded character set(字符编码集), code point(代码点), code space(代码空间),character encoding scheme(字符编码方案),code unit(编码单元),和3种Unicode常用的编码方式。
- character——字符,'a', '€', '中' 等, 都是一个字符
- character set——字符集,字符的集合
- coded character set——字符编码集,为每一个字符指定一个唯一的数字用来表示这个字符,这些数字组成的集合就是字符编**码集合,Unicode就是一个字符编码集
- code point——代码点,是一个数字,用来表示字符集中的一个字符,也就是字符编码集中的一个数,例如 Unicode 编码中, 'A'的code point就是65(在Unicode中通常写作 U+0041)
- code space——代码空间,就是一个编码集中,code point的范围, 例如 Unicode 编码的 code space 就是 0x0000 - 0x10FFFF
- character encoding scheme——字符编码方案,它定义了将字符用一个或多个固定长度的代码单元的方案,如前文提到的"utf-8编码方式"就是一个字符编码方案,其它的还有UTF16,UTF32,GBK等等
- code unit——编码单元,就是编码方案中固定长度的最小编码单元,如UTF8的编码单元是1bit,UTF16是2bit,UTF32是4bit,
Unicode常用的三种编码方式 UTF-8, UTF-16, UTF-32, 下面以辅助平面中的字符'