Oracle中一个汉字占几个字节

Oracle中一个汉字占几个字节?

某天,在向一个字段类型为CHAR(6)的表中插入数据’大沽口’时报错,提示’too large for column(actual: 9 ,maximum: 6)’。

我这眉头一皱,发现了事情没有这么简单。怎么办?百度!下面直接放结论:

  • N开头的字段类型(比如NCHAR,NVARCHAR2)中,任何一个字符(包括一个汉字)占2个字节,统一的。
  • 不以N开头的字段类型(比如CHAR,VARCHAR2)中,部分unicode字符(比如汉字)占3个字节,其它字符占1个字节

实践一下

Length 函数求得是占用字符数,lengthb或者vsize函数求得是占用字节数。

select length(‘测试1’) from dual –返回3,占用3个字符

select lengthb(‘测试1’) from dual –返回7,占用7个字节,其中汉字占3个字节,数字占一个字节

select length(N’测试1’) from dual –返回3,占用3个字符

select lengthb(N’测试1’) from dual –返回6,这是将字符串转换成为Unicode字符串后,每个字符占用2个字节

测试完之后,我不禁陷入了沉思:数据库字符集是UTF-8,一个中文占三个字节,当把中文转换为Unicode字符之后却只占2个字符。这是为啥呢?接着收集资料。

为何Unicode中文字符占取2个字节,而 UTF-8却占3个字节?

发明 UTF-8的初衷是为了修正Unicode中任何字符至少占用2个字节的弊端。虽然UTF-8英文字符占空间减少了(由Unicode中的16位动态缩减为与ASCⅡ一致的8位),但在中文字符这部分增为3字节=24位,减少的空间一下子又没了。

Unicode符号范围UTF-8编码方式说明
(十六进制)(二进制)#Unicode部分为16进制编码, UTF-8编码为2进制
0000 0000-0000 007F0xxxxxxx#UTF-8规定,若1字符=1字节,首位须为‘0’
0000 0080-0000 07FF110xxxxx 10xxxxxx#UTF-8规定,若1字符=2字节,高位字节前3位为‘110’,低位前2位为‘10’
0000 0800-0000 FFFF1110xxxx 10xxxxxx 10xxxxxx#UTF-8规定,若1字符=3字节,高位字节前3位为‘110’,后面低位前2位一律为‘10’。(占4,5字节字符规则以此类推)

由于UTF-8规则天然占用字节前几位,若与Unicode同样用2字节16位表示一个中文字符,则utf-8除去规则占用,只剩余16-5=11位,无法存储中文,只能再增加一个字节,1字符=3字节,除去规则占用,还剩余8×3-8=16位,恰好符合16位=1中文字符这一Unicode规则

举个例子:

已知“严”的Unicode是4E25(100111000100101),根据上表,可以发现4E25处在第三行的范围内(0000 0800-0000 FFFF),因此“严”的UTF-8编码需要三个字节,即格式是“1110xxxx 10xxxxxx 10xxxxxx”。然后,从“严”的最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了,“严”的UTF-8编码是“11100100 10111000 10100101”,这是保存在计算机中的实际数据,转换成十六进制就是E4B8A5

[参考地址][https://www.zhihu.com/question/23374078/answer/134244691]

补充

UTF-8英文1字节中文3字节,在编码效率和编码安全性之间做了平衡,适合网络传输,是理想的中文编码方式。UTF-8最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度
GBK英文1字节(半角1字节,全角2字节),中文2字节,GBK的范围比GB2312广,GBK兼容GB2312。
Unicode编码则是采用双字节16位来进行编号,可编65536字符

    原文作者:愚者的旋律
    原文地址: https://blog.csdn.net/qq_32202099/article/details/99680534
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞