Oracle的varchar2的最大长度,编码问题
varchar2
的类型:
Oracle
字段长度设置为varchar2(4000)
,
1.当数据库的字符集设置成
gb2312
,一个汉字占两个字节,可以放2000个汉字,2.当数据库的字符集设置成
utf-8
则,一个汉字占三个字节,只能存4000/3 = 1300
多点;
oracle数据库编码SIMPLIFIED CHINESE_CHINA.ZHS16GBK
,Java后台统一用UTF-8
,数据库也能插入中文的原因:
数据库在存放项目数据的时候会先用UTF-8
格式将数据解码成字节码,然后再将解码后的字节码重新使用GBK
编码存放到数据库中;
在从数据库中取数据的时候,数据库会先将数据库中的数据按GBK
格式解码成字节码,然后再将解码后的字节码重新按UTF-8
格式编码数据,最后再将数据返回给客户端。
GBK
对应SIMPLIFIED CHINESE_CHINA.ZHS16GBK
ORACLE的VARCHAR2是字节还是字符
往Oracle
一个表的VACHAR2(20)
字段中插入七个汉字,提示错误:插入的值太大。
改成插入六个汉字,又可以。
于是百度,原来这与ORACLE
的字符集设置有关。(以前的项目都是设置成的ZHS16GBK
)
字符集设置成ZHS16GBK
:汉字占2个字节。
字符集设置成AL32UTF8
:汉字占3个字节。
查询字符集:
select * from v$nls_parameters t where t.PARAMETER='NLS_CHARACTERSET';
oracle数据库中varchar2陷阱
oracle数据库相信大家都比较熟悉,数据库中有一种非常常用的数据类型:字符串型。
对应该类型,在oracle中有三种比较常用的类型:varchar2(byte)、varchar2(char)、nvarchar2()
。
那么这三种类型到底有什么区别呢?
首先,我们要时刻记清:无论是varchar2
还是nvarchar2
,最大字节数都是4000
。
varchar2(byte)
:就是默认的表示方式,比如我们写成:varchar2(100)
,就相当于varchar2(100 byte)
,表示最大字节数是100,该字段最多能容纳100个字节,强调空间大小。由于我们描述的是字节,因此,保存汉字等字符时,就要小心了。如果你的数据库用的是GBK
编码,那么一个汉字将占用2
个字节,最多能存50
个汉字,如果你的数据库用的是UTF8
编码,那么一个汉字将占用3个字节,最多能存33
个汉字。
varchar2(char):表示最大字符数是100
,该字段最多能容纳100
个字符,强调个数。假设我们写成varchar2(100 char)
,那么无论是数字、字母、汉字,都看成一个字符,最多写100个,当然,汉字越多,占用的空间越大,同样遵循上边的数据库编码原则。例如:存入一个汉字,底层占2或3个字节,存入一个字母,占1个字节,绝对不是某些文章所说1个字母或数字也占2或3个字节!
nvarchar2()
:没有byte、char
之分,类似于varchar2(char)
,只不过nvarchar2()
屏蔽了数据库编码,无论是何种编码,nvarchar2()中一个汉字都占两个字节。
一般的教程,也就到这了,可是如果再多一步思考,会发现一个致命问题。
实际应用中,很可能会出现这种写法:varchar2(1400 char)
,我们主观的认为,这个字段最长不能超过1400
个字符,这意味着我们可能会存入1399
个字符,貌似很正确的样子。
但是,如果这1399
个字符都是汉字,字符长度并没有超过1400
,看起来一切正常,但实际上我们损失了一部分数据,为什么?
因为1399
个汉字,按UTF8
编码来说(99%的项目都是UTF8编码吧。。),需要占用1399*3=4197
个字节,而文章开篇就说,无论是什么char,最大长度就是4000
字节,一个也不能多,因此多出来的197
个字节,都会抹去,而整个过程中,无任何错误提示,你的数据就这样蒸发了!
所以,对于GBK
编码的数据库而言,安全的写法为:varchar2(2000 char)、nvarchar2(2000)
,对于UTF8
编码的数据库而言,安全的写法为:varchar2(1333 char)、nvarchar2(2000)
。