Oracle的N-数据类型困惑
Posted bisal
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle的N-数据类型困惑相关的知识,希望对你有一定的参考价值。
Oracle中存储字符串,我们通常会用CHAR、VARCHAR2等,但是有时就会碰到使用NCHAR、NVARCHAR2的情况,当做数据迁移时,格外要注意,避免因为存储空间的问题,导致插入失败。
谈到N-数据类型,不得不提到国家字符集(National Character Set),国家字符集是用于像NCHAR、NVARCHAR2、NCLOB这种数据类型的,他是由参数NLS_NCHAR_CHARACTERSET控制。普通的数据库字符集,则用于CHAR、VARCHAR2、LONG和CLOB数据类型的,则是参数NLS_CHARACTERSET控制的。
从9i开始,NLS_NCHAR_CHARACTERSET只能有2个取值,UTF8或者AL16UTF16,默认值是AL16UTF16,如果无特殊需求,推荐用该值。
使用国家字符集的数据类型主要有三种,
NCHAR - 定长类型的国家字符集字符串,列的长度按照字符个数计算(即CHAR的语义)。
NVARCHAR2 - 变长类型的国家字符集字符串,列的长度按照字符个数计算(即CHAR的语义)。
NCLOB - 存储最多4GB字符串,即使NLS_NCHAR_CHARACTERSET定义为UTF8,在这种数据类型,数据都会按照UCS2或者AL16UTF16进行存储,影响有限,具体可参考Possible action for CLOB/NCLOB storage after 10g upgrade(Doc ID 258114.1)。
CHAR语义和BYTE语义,可以参考《NLS_LENGTH_SEMANTICS参数引申的问题》,N-类型只能定义为CHAR语义,不能定义为BYTE语义。
The National Character Set(NLS_NCHAR_CHARACTERSET) in Oracle 9i, 10g , 11g and 12c (Doc ID 276914.1)给了一张图,
从图上可知,如果字符集是UTF8,最小需要1个字节存储,4000/1=4000,4000是字段可定义的最大长度,最大需要3个字节存储,例如中文,4000/3=1333+1,1333是字段可定义的最大长度。
如果用的AL16UTF16,都是按照2个字节存储,可以体验下,
因此字段可定义的最大长度就是2000,如下所示,超过就提示错误,
SQL> create table t1(id nvarchar2(2001));
create table t1(id nvarchar2(2001))
*
ERROR at line 1:
ORA-00910: specified length too long for its datatype
定义为2000,才可执行,
SQL> create table t1(id nvarchar2(2000));
Table created.
但是虽然我们定义了NVARCHAR2(2000),实际插入超过2000的字符,并不会提示错误,
SQL> update t1 set id = lpad('你', 4000, '你');
1 row updated.
然而实际存储的,是截断的,所以要注意,
如果数据库采用Unicode作为默认字符集,其实没任何必要用到NVARCHAR2类型,而且在Oracle关于国际化的官方文档中,推荐使用AL32UTF8字符集。这个帖子,解释的很明白,
https://community.oracle.com/mosc/discussion/comment/11489625
VARCHAR2和NVARCHAR2在使用上的一些问题,
因此,数据库采用UTF8字符集就可以忽略国家字符集了,
近期更新的文章:
《问题定位的思考》
《国足世界杯畅想》
《小白学习MySQL - varchar类型字段为什么经常定义成255?》
文章分类和索引:
以上是关于Oracle的N-数据类型困惑的主要内容,如果未能解决你的问题,请参考以下文章