Oracle数据类型及存储方式——字符类型篇

来源:互联网 发布:淘宝卖家 转账20万 编辑:程序博客网 时间:2024/04/28 17:40
注:这篇文章绝大部分都摘抄于袁光东先生的  <<oracle小组学习笔记>>.

下面会对各种字符类型作详细解释。

一. char 类型

oracle 可以定义1个char(n)类型的列,长度为n, 如果插入数据长度小于n,   会自动用空格补齐。  n<=2000

1.新建1个表test_char,只含1个列,类型是char(10).  列名是colA.
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
2.向这张表插入一d数据。
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011

注:最多只能插入10个字符 否则报错。(废话拉)

3.使用dump函数可以查看每1条数据的内部存储结构。
注:dump 函数能查看数据在datafile存储内容。


解释一下:
Typ=96 表示数据类型的ID。  其中char类型的id是96。
Len=10 表示所在的内部存储的长度(用字节表示). 虽然第一行数据知存了1个字符'a',但是它还是占了10个字节的空间。
97,32,32,32,32,32,32,32,32,32  表示内部存储方式。 其实oracle的内部存储方式是以ASCII码来存储的。

点解咁讲? 因为97就是a的ASCII码、。

可以用chr 函数把ASCII码转成字符:
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
反之,如果想知道1个字符的ASCII码,可以用函数ascii:


而32是空格的ASCII码。
所以由97,32,32,32,32,32,32,32,32,32 得知char类型是定长类型,它总会
用空格来填充以达到1个固定宽度。
所以用char类型来保存字符数据是比较浪费空间的,如果字符数据很长的话。

oracle 的数据类型长度单位是字节:
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
 
可见1个汉子在oracle 是占用了两个字节的。
英文字母或符号只占用1个字节。
Char(10)最多可以存放5个汉字。


二. varchar2 类型
varchar2 是oracle 特有数据类型, 可以看成是sybase的varchar类型。
varchar2是按实际长度保存数据的。最多可以占用4000个字节。

1. 创建1个表,只有1列, 类型为varchar2, 长度为10。列名为colB.
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
2.插入一些数据
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
3. 用dump函数查看每一行的内部存储结构。
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
Typ=1 说明varchar2类型在oracle中的类型编号为1
Len 代表了每一行数据所占用的字节数,可以睇到没一行的len都唔同。
后面是 ASCII码

由此可见,varchar2 是存多少就占用多少空间。比较节省硬盘空间,不会用空格来填充。



三. byte 和 char

从10g开始, 在字符类型的宽度定义时,可以指定单位。
Byte 就是字节
char 就是字符。

Varchar2(10 byte) 长度是10个字节。
varchar2(10 char) 长度是10个字符所占的长度。
char(10 byte)长度是10个字节。
char(10 char)长度是10个字符所占的长度

注: varchar2(10) 默认为 varchar2(10 byte)

而1个字符占用多少个字节。 是由当前系统所采用的字符集来决定的。
如1个汉子占用两个字符。

查看当前系统所采用的字符集
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
 

如果在定义类型是,不指定单位,默认是按byte. 即系以字节为单位的。

采用char为单位的好处是,可以使用多字节的字符集。
比如, 在ZHS16GBK 字符集中, 1个汉字占两个字符。

那么如果把table的某个column的长度定义为可存放10个汉字, 通过下面定义就可以了
Create table table_name(col_name varchar2(10 char))

继续实验, 新建1张表, 包含两列。1列采用byte为单位, 1列采用char为单位。
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
如上
col_char 列,定义为可以存放10个字符。
col_byte列, 定义为可以存放10个字节的字符。

当前的系统采用字符集为ZHS16GBK,所以1个汉字字符占两个字节。

试着在表中插入一些数据。
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011

如上, col_char 可以插入10个汉字(每个两个字节), 而col_byte 可以插入10个字节(每个字母占1个字节)。
   
而,当我们向col_byte 插入6个汉字时,就会报错,因为6个汉字已经超出10个字节了。
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 

再看看col_char中每一行的存储结构
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
可以见到,当我们向col_char插入10个汉字时,它的长度为20.
尽管我们定义时采用varchar2(10,char)
由此可见,oracle 是根据当前数据采用的字符集,每个汉字字符所占字节数X 字符 来决定了
该字段所占的字节数。

在本例中(11g),varchar2(10, char) 并不等于  varchar2(20)
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
因为向col_char插入'aaaaaaaaaaa' (11个a)时会报错, 因为已经超过11个字符!
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 

当采用多字节的字符集时,定义字段长度还是采用char 为单位为佳, 因为可以避免字段长度的问题。

当不知道当前数据采用的字符集,1个字符占用多少字节时,可以使用lengthb函数。
注意与length函数的区别哦

四, char 还是 varchar

1.就建1张表,一列为char类型, 一列为varchar2类型, 长度都是20byte.
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011

2.想该表的两列都插入相同的数据。
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
3. 分别 以char_col 列和 varchar_col列为条件查询
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 

睇起身貌似无咩区别。

5.在继续睇下面的例子
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
 
上面可以睇出他们其实不一样, char(20)类型会将 'Hello world' 变成 ‘Hello world     ' 来存储。         
当对比 char类型的列 和 常量时, 两边都会做Rtrim 处理(删掉右边空格)
所以
select * from test_char_varchar where char_col = 'Hello World'
相当于:
select * from test_char_varchar where rtrim(char_col) = rtrim('Hello World')

但是当char类型列和varchar2类型列对比时,   是不会做这种处理的
既系
 'Hello world' != ‘Hello world     ' 


如果要让char_col 列 与varchar_col列相等, 有两种办法
第一种是: 使用rtrim 把char_col列右边的空格去掉。
第二种是:使用rpad 把 varchar_col右边用空格填充。
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
注意: 如果使用rtrim函数, 那么使用rtrim 函数的列的索引失效, 除非那个列的索引本身就是使用rtrim 的函数索引。
此外还会绑定变量时出现问题。



五, nchar 和 nvarcahr2
如果系统需要集中管理和存储多种字符集, 就需要使用这两种字符类型。 在使用nchar 和
nvarchar2时, 文本内容采用国家字符集来存储和管理,而不是当前数据库的字符集。

这两种类型的长度制定的是字符数,而不是字节数。
NLS 国家语言支持(National Language Support)

在oracle 9i 以后的版本, 数据库的国家字符集可以是: utf-8 和 AL16UTF-16两种。

1.新建1个表, 有两列, 类型分别是 nchar 和 nvarchar2 长度都是10.
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
2.插入一些数据
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
在9i 之前的版本,插入时加上N时, 在处理时跟普通方式有区别。
但是在10g时已经有了改变,加不加N都一样,这里只是为了测试。
再插入一行数据
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011

3. 查看每行 col_nchar列的存储方式.
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
 
Typ=96 与char的类型编码一样。
Len=20 每一行的长度都是20字节。 跟char 一样都是定长。 但是char(10)长度是10,而nchar(10)长度
             是20字节。也就是说,统统以两个字节来表示1个字符。

150,72 表示陈
0,97 表示'a'
0,32 表示空格。

4. nvarchar2的存储
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
Typ=1 与varcahr2一样。
但是每一行的len值都不全相同, 也就系讲唔会用空格来填充。 与varchar2一样
每1个字符都会用两个字节来存储,跟nchar一样
b 存储为 0.98
陈希比 存储为 150,72,94,12,107,212

5.nchar 与 nvarchar2的数据定义。
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
注意虽然类型是写着nchar(10),实际上长度是20字节的。
所以一张表某列如果能保证数据都是字母数字, 用char(10), 是比nchar(10)节省1半空间的。

需要注意的是: 在char(or varchar2) 和 nchar(or nvarchar2) 对汉字的实际存储值是不一样的,因为采用了不同的字符集,就会有
不用的字符编码。

Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
这是采用的字符集系统是ZHS16GBK
可以很容易地把它转成ascii码
高位*256(2的8次方) + 低位
179*256 + 194 = 46018

而46018正好就是汉字’陈‘的 ascii码
Oracle数据类型及存储方式——字符类型篇 - 饥民 - 饥民2011
 
而在nchar 和 nvarchar2中, 采用的是UTF-8 或 UTF-16 的字符集。
由上面例子得知汉字 '陈’ 在 nchar 中 存储为 150,72. 与ascii码是不兼容的。









原创粉丝点击