在Java语言中,使用Unicode编码来表示数据,是最多占2个字节的!在程序运行时,数据是在内存的,根据不同的数据类型可以很好的区分相关的数据,但是,如果数据需要传输到内存以外,例如存储到硬盘中,或者传输到网络中,数据转换为二进制的序列,就无法被接收方正确的处理!
如果需要使用a
,它的二进制表示是110 0001
(忽略最高位的符号位),假设存在汉字程
的二进制是111 0011 1100 1011
(假设值),如果需要传输a程a
这样的字符串,则实际传输的二进制数是1110 0001 1111 0011 1100 1011 1110 0001
,当接收方收到这个数据以后,根本无从判断这到底是2个汉字,还是4个字母,或1字母1汉字1字母,或2字母1汉字、1汉字2字母。
所以,当数据需要传输到内存以外时,必须为这些数据再制定一些特殊的规律,使得接收方能明确的接收相应的数据!
UTF-8就是Unicode的传输编码(Unicode Transfermation Format),这种编码是将Unicode的基础之上添加了特定位数表示特定意义的,以在UTF-8中占2字节为例,二进制序列的格式是:
110 xxxxx 10 xxxxxx
即:只要是UTF-8中占2个字节的字符,第1个字节的前3位都是110
,第2个字节的前2位都是10
,这几个字节是有特殊意义的,不作为编码位,其中,110
中有2个1
,表示从这个字节开始,连接的2个字节是1个字符,第2个字节前面的10
表示前面的字节并没有完全表示1个字符,当前字节是继续表示同一个字符的。
UTF-8也可能使用3个字节来表示1个字符,当使用3个字节时,其格式是:
1110 xxxx 10 xxxxxx 10 xxxxxx
UTF-8也可能使用4个字节来表示1个字符,当使用4个字节时,其格式是:
11110 xxx 10 xxxxxx 10 xxxxxx 10 xxxxxx
所以,UTF-8编码最多可能使用4个字节来表示1个字符,在MySQL中,如果需要表示这种能识别4字节对应1字符的编码方式,需要将编码显式的设置为utf8mb4
,否则,默认的utf8
表示的是utf8mb3
。