oracle char与varchar2的比较与使用

本文详细对比了Oracle数据库中CHAR与VARCHAR2两种字符类型的差异,并介绍了如何选择使用这两种类型。此外,还探讨了Oracle中文字符的存储空间计算方法及LENGTH与LENGTHB函数的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近工作处理了一些有关oracle字符数据类型的问题,特做如下整理,希望和大家共同学习:

一、首先对char与varchar2类型做下比较:(以下部分内容转自华夏名网)

区别:

  1.CHAR的长度是固定的,而VARCHAR2的长度是可以变化的, 比如,存储字符串“abc",对于CHAR (20),表示你存储的字符将占20个字节(包括17个空字符),而同样的VARCHAR2 (20)则只占用3个字节的长度,20只是最大值,当你存储的字符小于20时,按实际长度存储。

例:

 SQL> create table testchar(c1 char(20), c2 varchar2(20));

表已创建。

SQL> insert into testchar values('dylan','dylan');

已创建 1 行。

SQL> commit;

提交完成。

SQL> select length(t.c1), length(t.c2) from testchar t;

LENGTH(T.C1) LENGTH(T.C2)
------------ ------------
          20            5

  2.CHAR的效率比VARCHAR2的效率稍高。

  3.目前VARCHAR是VARCHAR2的同义词。工业标准的VARCHAR类型可以存储空字符串,但是oracle不这样做,尽管它保留以后这样做的权利。Oracle自己开发了一个数据类型VARCHAR2,这个类型不是一个标准的VARCHAR,它将在数据库中varchar列可以存储空字符串的特性改为存储NULL值。如果你想有向后兼容的能力,Oracle建议使用VARCHAR2而不是VARCHAR。

 

何时该用CHAR,何时该用varchar2?

  CHAR与VARCHAR2是一对矛盾的统一体,两者是互补的关系.

  VARCHAR2比CHAR节省空间,在效率上比CHAR会稍微差一些,即要想获得效率,就必须牺牲一定的空间,这也就是我们在数据库设计上常说的‘以空间换效率’。

  VARCHAR2虽然比CHAR节省空间,但是如果一个VARCHAR2列经常被修改,而且每次被修改的数据的长度不同,这会引起‘行迁移’ (Row Migration)现象,而这造成多余的I/O,是数据库设计和调整中要尽力避免的,在这种情况下用CHAR代替VARCHAR2会更好一些。

 

二、关于oracle中文字符占用多少存储空间问题

 

方法一:
一个汉字在Oracle数据库里占多少字节跟数据库的字符集有关,UTF8时,长度为3.

测试一个汉字在各种字符集中到底占用多少字节:

SQL> select    lengthb('汉')    from    dual;

LENGTHB('汉')
-------------
            2

方法二:

查看oracle数据库当前字符集:

SQL> select * from nls_database_parameters where parameter='NLS_CHARACTERSET';

PARAMETER                      VALUE
------------------------------ ----------------------------------------------------------------
NLS_CHARACTERSET               ZHS16GBK


一个英文字母是一个字符,一个中文汉字是几个字符呢?我们知道,一个中文汉字是双字节字符,但它有几个字符与其数据库字符集有关。如果数据库字符集使用单字节US7ASCII,则一个中文汉字是二个字符;如果数据库字符集使用双字节字符集ZHS16GBK,则一个中文汉字是一个字符。有关这一点可以使用 Oracle的函数Substr得到证明。 


使用US7ASCⅡ字符集时: 

SQL> select substr('南京大学',1,2) from dual;

SUBS
----

 

使用ZHS16GBK字符集时: 

SQL> select substr('南京大学',1,2) from dual;

SUBS
----
南京

三、关于length与lengthb函数的比较与使用:以下内容转自tianlesoftware大神

在不同的数据库,因为字符集的不同,LENGTHB得到的值可能会不一样。如ZHS16GBK采用两个byte位来定义一个汉字。而在UTF8,采用3个byte。

 

SQL>SELECT USERENV('LANGUAGE') FROM DUAL;

 

USERENV('LANGUAGE')

----------------------------------------------------

AMERICAN_AMERICA.ZHS16GBK

 

 

SQL>select length('北大') from dual;

2

SQL>select lengthb('北大') from dual;

4

 

SQL>select length('Beida') from dual;

5

SQL>select lengthb('Beida') from dual;

5

 

通过这个示例,我们可以看出来,Length 和 Lengthb 函数的一个重要用处,就是用来判断记录值里是否有中文内容。

 

如果有中文,那么Length() != Lengthb()

如果没有中文,那么Length() == Lengthb()

 

 

 

made by dylan.

<think>好的,我现在要详细分析Oracle数据库varchar2char数据类型的区别以及它们的使用场景。首先,我需要回顾一下用户提供的引用内容,确保信息准确无误。 根据引用[2]和引用[5],charvarchar2都是字符数据类型,但char是固定长度的,而varchar2是可变长度的。这意味着当存储的数据长度不足时,char会用空格填充到指定长度,而varchar2则不会,只会占用实际数据所需的空间。例如,如果定义CHAR(10),但只存储'abc',那么剩下的7个字符会用空格填充;而VARCHAR2(10)存储'abc'时,只占用3个字符的空间,节省了存储空间。 接下来要考虑的是存储效率。引用[3]提到,如果数据长度基本一致,使用char可以提高检索速度,因为固定长度更容易计算位置,但提取时需要处理多余的空格。而varchar2适合数据长度变化大的情况,避免空间浪费。例如,存储用户姓名时,长度可能差异较大,用varchar2更合适。 然后是字符集的问题。引用[4]提到varchar2可以指定存储的是字节还是字符,这在多语言环境中很重要。比如,使用UTF-8时,一个字符可能占用多个字节,定义VARCHAR2(10 CHAR)可以存储10个字符,无论每个字符占用多少字节。而char可能更适合单字节字符集的固定长度数据。 性能方面,引用[5]指出,char的固定长度在查询时更快,因为不需要计算实际长度,而varchar2的变长可能在频繁更新时产生碎片,影响性能。但varchar2节省空间,适合存储大文本或变化大的数据。 使用场景的话,char适合像国家代码、固定长度的编码(如身份证号,如果统一长度),而varchar2适合姓名、地址等长度不固定的字段。此外,如果数据库需要移植到其他系统,如MySQL,可能需要考虑使用varchar而非varchar2,但根据引用[2],Oracle环境下优先用varchar2。 还要注意存储限制,char最大为2000字节,而varchar2Oracle 12c及以上可以到32767字节,但通常设置为4000字节。这影响大文本存储的选择,比如文章内容应该用varchar2或更大的CLOB类型。 最后总结两者的区别点,包括存储方式、空间使用、性能和应用场景,帮助用户根据具体情况选择合适的数据类型。</think>### Oracle数据库varchar2char数据类型的区别及使用场景 #### 1. **存储方式空间占用** - **CHAR**:固定长度类型,存储时会用空格填充至定义的长度。 例如:`CHAR(10)`存储字符串`"abc"`时,实际占用10字节(剩余7个字节用空格填充)[^2][^5]。 - **VARCHAR2**:可变长度类型,仅存储实际数据长度。 例如:`VARCHAR2(10)`存储`"abc"`时,仅占用3字节。 #### 2. **性能差异** - **CHAR**:由于固定长度,**检索速度更快**(存储位置计算简单),但提取时需用`TRIM()`处理末尾空格[^3][^5]。 - **VARCHAR2**:节省存储空间,但频繁更新变长数据可能导致**行迁移**,影响性能。 #### 3. **字符集处理** - **VARCHAR2**支持按字符(`CHAR`)或字节(`BYTE`)定义长度。例如: ```sql VARCHAR2(10 CHAR) -- 存储10个字符(适合多字节字符集如UTF-8) VARCHAR2(10 BYTE) -- 存储10字节(适合单字节字符集) ``` 这在多语言环境中更灵活,可避免字符转换问题[^4][^3]。 - **CHAR**默认按字节定义长度,需手动指定`CHAR`单位。 #### 4. **使用场景** - **CHAR适用场景**: - 数据长度**严格固定**(如国家代码`"CN"`、性别`"M"/"F"`)[^5]。 - 需要快速查询的字段(如主键或高频检索字段)。 - **VARCHAR2适用场景**: - 数据长度**变化较大**(如姓名、地址、描述文本)。 - 存储空间敏感或需要支持多语言(减少乱码风险)。 #### 5. **存储限制** - **CHAR**最大长度为**2000字节**。 - **VARCHAR2**在Oracle 12c及以上版本支持最大**32767字节**(需开启扩展模式),默认上限为4000字节[^4]。 --- ### 总结对比 | **特性** | **CHAR** | **VARCHAR2** | |-------------------|------------------------------|------------------------------| | **存储方式** | 固定长度,空格填充 | 可变长度,无填充 | | **空间效率** | 低(适合固定长度数据) | 高(适合变长数据) | | **查询性能** | 更快(固定长度计算简单) | 稍慢(需处理变长数据) | | **字符集支持** | 默认按字节,需手动指定字符 | 支持按字符或字节定义 | | **典型场景** | 国家代码、固定编码、高频检索 | 姓名、地址、多语言文本 | ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值