Oracle字符集与字符类型存储空间占用

简介: 数据库的全球化特性是数据库发展的必然结果,位于不同地区、不同国家、不用语言而使用同一数据库越来越普遍。

数据库的全球化特性是数据库发展的必然结果,位于不同地区、不同国家、不用语言而使用同一数据库越来越普遍。对于不同国家或地区数据库通常会使用不同的字符集,而全球性企业也会选择使用统一编码的数据库字符集。Oracle数据库统一字符集为AL32UTF8,可以参考:Oracle 全球化特性与字符集。对于不同的字符集容易出现转换乱码,同时不同字符集也影响存储空间的占用。 如本文下面的描述。

一、字符集环境变量对数据库的影响

[oracle@java_1 ~]$ env |grep LANG
LANG=zh_CN.UTF-8    ###OS环境变量

SQL> select * from v$version where rownum<2;  --当前数据库版本

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

SQL> col value format a40
SQL> select * from nls_database_parameters where parameter like '%CHARACT%';

PARAMETER                      VALUE  
------------------------------ ----------------------------------------
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               AL32UTF8    ---数据库字符集
NLS_NCHAR_CHARACTERSET         AL16UTF16   ---国家字符集

SQL> select dump('云') from dual;          ---当前dump出来使用了9个字节

DUMP('???')
-------------------------------------------------
Typ=96 Len=9: 239,191,189,239,191,189,239,191,189

[oracle@java_1 ~]$ env |grep LANG
LANG=en_US.UTF-8        ###将OS环境修改为英语与美国地区 

SQL> select dump('云') from dual;  

DUMP('???')   ---当前dump出来依旧使用了9个字节,也即是证明了UTF-8为统一编码,与语言地域无关
-------------------------------------------------
Typ=96 Len=9: 239,191,189,239,191,189,239,191,189

###下面设置环境变量NLS_LANG,如下
[oracle@java_1 ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.AL32UTF8"
[oracle@java_1 ~]$ env |grep LANG
NLS_LANG=SIMPLIFIED CHINESE_CHINA.AL32UTF8
LANG=zh_CN.UTF-8

SQL> select dump('云') from dual;  ---当前dump出来使用了3个字节

DUMP('云')            
-------------------------
Typ=96 Len=3: 228,186,145

###下面设置环境变量NLS_LANG,字符集使用ZHS16GBK
[oracle@java_1 ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"
[oracle@java_1 ~]$ env |grep LANG
NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
LANG=zh_CN.UTF-8

SQL> select dump('云') from dual;  --此时报错
ERROR:
ORA-01756: ?

###下面将其设置为繁体字符集,报ORA-12705,如下:
[oracle@java_2 ~]$ export NLS_LANG="CHINESE_TAIWAN.ZHT16MSWIN950"
[oracle@java_2 ~]$ sqlplus robin/xxx

SQL*Plus: Release 11.2.0.1.0 Production on Sun May 15 10:21:37 2016

Copyright (c) 1982, 2009, Oracle.  All rights reserved.

ERROR:
ORA-12705: Cannot access NLS data files or invalid environment specified

二、字符集对字符类型存储空间的影响

1、数据库字符集为AL32UTF8的情形

[oracle@java_1 ~]$ unset NLS_LANG   ###不设置环境变量NLS_LANG
[oracle@java_1 ~]$ env|grep LANG
LANG=zh_CN.UTF-8

SQL> create table tb_length(id int,col1 varchar2(20), col2 nvarchar2(20));

SQL> insert into tb_length values(1,'云创','云创');

SQL> commit;

SQL> select vsize(col1),vsize(col2) from tb_length;

VSIZE(COL1) VSIZE(COL2)   --如结果,对于varchar2,一个汉字使用了9个字节
----------- -----------   --对于nvarchar2,一个汉字使用了6个字节
         18          12

###下面设置NLS_LANG
[oracle@java_1 ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.AL32UTF8"
[oracle@java_1 ~]$ env|grep LANG
NLS_LANG=SIMPLIFIED CHINESE_CHINA.AL32UTF8
LANG=zh_CN.UTF-8

SQL> insert into tb_length values(2,'数据','数据');

SQL> commit;

SQL> select vsize(col1),vsize(col2) from tb_length where id=2;

VSIZE(COL1) VSIZE(COL2)           --如结果,对于varchar2,一个汉字使用了3个字节  
----------- -----------           --对于nvarchar2,一个汉字使用了2个字节
          6           4

SQL> select vsize(col1),vsize(col2) from tb_length;

VSIZE(COL1) VSIZE(COL2)
----------- -----------
         18          12
          6           4

2、数据库字符集为ZHS16GBK的情形(以下为不同环境及版本的数据库)

SQL> select * from v$version where rownum<2;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production

SQL> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.ZHS16GBK

SQL> select * from nls_database_parameters where parameter like '%CHARACT%';

PARAMETER                      VALUE
------------------------------ ----------------------------------------
NLS_NUMERIC_CHARACTERS         .,
NLS_CHARACTERSET               ZHS16GBK
NLS_NCHAR_CHARACTERSET         AL16UTF16

SQL> ho env|grep LANG
LANG=zh_CN.UTF-8

SQL> create table tb_length(id int,col1 varchar2(20), col2 nvarchar2(20));

SQL> insert into tb_length values(1,'云创','云创');

SQL> select vsize(col1),vsize(col2) from tb_length;

VSIZE(COL1) VSIZE(COL2)         --如结果,对于varchar2,一个汉字使用了3个字节
----------- -----------         --对于nvarchar2,一个汉字使用了6个字节
          6          12

###下面设置NLS_LANG
[oracle@java_2 ~]$ export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"
[oracle@java_2 ~]$ env |grep env
_=/bin/env
[oracle@java_2 ~]$ env |grep LANG
NLS_LANG=SIMPLIFIED CHINESE_CHINA.ZHS16GBK
LANG=zh_CN.UTF-8

SQL> insert into tb_length values(2,'数据','数据');

SQL> commit;

SQL> select vsize(col1),vsize(col2) from tb_length;

VSIZE(COL1) VSIZE(COL2)
----------- -----------
          6          12   --Author : Leshami  Blog: http//blog.csdn.net/leshami
          6           6   --设定NLS_LANG之后,varchar2与nvarchar2占用空间一致

3、不同varchar2长度定义对存储空间的影响

SQL> create table tb_length2(col1 varchar2(20),col2 varchar2(30));

SQL> insert into tb_length2 values('云创数据','云创数据');

SQL> select vsize(col1),vsize(col2) from tb_length2;

VSIZE(COL1) VSIZE(COL2)
----------- -----------     --存储空间都为12个字节,而不论定义长度的多少
         12          12

三、常用的NLS_LANG设置

Commonly Used Values for NLS_LANG 
Table C-1 lists commonly used NLS_LANG values for various operating system locales: 
Table C-1 NLS_LANG Parameter Values 
Operating System Locale          NLS_LANG Value 
---------------------------    -----------------------------------------
Chinese (PRC)                    SIMPLIFIED CHINESE_CHINA.ZHS16GBK
Chinese (Taiwan)                 TRADITIONAL CHINESE_TAIWAN.ZHT16MSWIN950
English (United Kingdom)       ENGLISH_UNITED KINGDOM.WE8MSWIN1252
English (United States)        AMERICAN_AMERICA.WE8MSWIN1252
French  (Canada)               CANADIAN FRENCH_CANADA.WE8MSWIN1252
French  (France)                 FRENCH_FRANCE.WE8MSWIN1252
German  (Germany)                GERMAN_GERMANY.WE8MSWIN1252
Japanese                         JAPANESE_JAPAN.JA16SJIS
Korean                         KOREAN_KOREA.KO16MSWIN949
Russian                        RUSSIAN_CIS.CL8MSWIN1251          

四、小结

1、注意LANG与NLS_LANG,前者是设置操作系统级别环境语言及字符集变量,后者是针对数据库级别
2、在未设置NLS_LANG的情形下,导致被存储的字符数量尺寸过大
3、NLS_CHARACTERSET为数据库字符集,NLS_NCHAR_CHARACTERSET为国家字符集
4、当数据库字符集为AL32UTF8的情形下,nvarchar2存储尺寸小于varchar2存储尺寸,建议使用nvarchar2存储国家字符集。
5、当数据库字符集为ZHS16GBK的情形下,varchar2与nvarchar2占用空间一致。用那种类型都无所谓。
6、varchar2(20)与varchar2(50)在存储相同内容时,所占用的空间一样。仅仅用于限制列长度。
7、参考:Oracle 全球化特性与字符集 264157.1

目录
相关文章
|
10月前
|
SQL Oracle 关系型数据库
Oracle查询优化-将字符和数字分离
【2月更文挑战第4天】【2月更文挑战第9篇】将字符和数字分离
78 2
|
2月前
|
Oracle 关系型数据库 数据库
【YashanDB知识库】oracle dblink varchar类型查询报错记录
在使用Oracle DBLink查询VARCHAR类型数据时,可能会遇到多种报错。通过了解常见错误原因,采取合适的解决方法,可以有效避免和处理这些错误。希望本文提供的分析和示例能帮助你在实际工作中更好地处理DBLink查询问题。
67 10
|
7月前
|
存储 自然语言处理 Oracle
Oracle数据库字符集概述及修改方式
【8月更文挑战第15天】Oracle 数据库字符集定义了数据的编码方案,决定可存储的字符类型及其表示方式。主要作用包括数据存储、检索及跨系统传输时的正确表示。常见字符集如 AL32UTF8 支持多语言,而 WE8MSWIN1252 主用于西欧语言。修改字符集风险高,可能导致数据问题,需事先备份并评估兼容性。可通过 ALTER DATABASE 语句直接修改或采用导出-导入数据的方式进行。完成后应验证数据完整性。此操作复杂,须谨慎处理。
247 5
|
3月前
|
存储 Oracle 关系型数据库
服务器数据恢复—华为S5300存储Oracle数据库恢复案例
服务器存储数据恢复环境: 华为S5300存储中有12块FC硬盘,其中11块硬盘作为数据盘组建了一组RAID5阵列,剩下的1块硬盘作为热备盘使用。基于RAID的LUN分配给linux操作系统使用,存放的数据主要是Oracle数据库。 服务器存储故障: RAID5阵列中1块硬盘出现故障离线,热备盘自动激活开始同步数据,在同步数据的过程中又一块硬盘离线,RAID5阵列瘫痪,上层LUN无法使用。
|
4月前
|
存储 Oracle 关系型数据库
【赵渝强老师】Oracle的物理存储结构
Oracle的物理存储结构包括数据文件、联机重做日志文件、控制文件、归档日志文件、参数文件、告警日志文件、跟踪文件和备份文件。这些文件在硬盘上存储数据库的各种数据和日志信息,确保数据库的正常运行和故障恢复。视频讲解和详细说明见原文。
|
8月前
|
存储 Oracle 关系型数据库
关系型数据库Oracle备份类型与频率
【7月更文挑战第21天】
128 6
|
8月前
|
存储 监控 Oracle
关系型数据库Oracle空间不足
【7月更文挑战第15天】
86 6
|
8月前
|
SQL Oracle 关系型数据库
关系型数据库Oracle备份类型
【7月更文挑战第18天】
91 2
|
8月前
|
存储 Oracle 关系型数据库
关系型数据库Oracle 空间不足
【7月更文挑战第16天】
88 2
|
7月前
|
分布式计算 Oracle 关系型数据库
实时计算 Flink版产品使用问题之获取Oracle的数据时无法获取clob类型的数据,该怎么办
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。