数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

Oracle数据类型及存储方式


发布日期:2022年12月16日
 
Oracle数据类型及存储方式

概述

通过实例全面而深入的分析oralce的基本数据类型及它们的存储方式以ORACLE G为基础介绍oralce g引入的新的数据类型让你对oracle数据类型有一个全新的认识揭示一些不为人知的秘密和被忽略的盲点从实用和优化的角度出发讨论每种数据类型的特点从这里开始oracle之旅!

第一部份 字符类型

§ char

定长字符串会用空格来填充来达到其最大长度最长个字节

. 新建一个测试表test_char只有一个char类型的列长度为

SQL> create table test_char(colA char());

Table created

. 向这个表中插入一些数据

SQL> insert into test_char values(a);

row inserted

SQL> insert into test_char values(aa);

row inserted

SQL> insert into test_char values(aaa);

row inserted

SQL> insert into test_char values(aaaa);

row inserted

SQL> insert into test_char values(aaaaaaaaaa);

row inserted

注意最多只能插入个字节否是就报错

SQL> insert into test_char values(aaaaaaaaaaa);

insert into test_char values(aaaaaaaaaaa)

ORA: value too large for column PUB_TESTTEST_CHARCOLA (actual: maximum: )

. 使用dump函数可以查看每一行的内部存数结构

SQL> select colA dump(colA) from test_char;

COLA DUMP(COLA)

a Typ= Len=:

aa Typ= Len=:

aaa Typ= Len=:

aaaa Typ= Len=:

aaaaaaaaaa Typ= Len=:

注意Typ= 表示数据类型的IDOracle为每一种数据类型都进行了编号说明char类型的编号是

Len = 表示所在的内部存储的长度(用字节表示)虽然第一例只存了一个字符a但是它还是占用了个字节的空间

表示内部存储方式可见oracle的内部存储是以数据库字符集进行存储的

正好是字符a的ASCII码

可以使用chr函数把ASCII码转成字符

SQL> select chr() from dual;

CHR()

a

要想知道一个字符的ASCII码可以使用函数ascii

SQL> select ascii(a) from dual;

ASCII(A)

正好是空格的ascii码值

Char类型是定长类型它总会以空格来填充以达到一个固定宽度

使用char类型会浪费存储空间

Oracle的数据类型的长度单位是字节

SQL> select dump() from dual;

DUMP()

Typ= Len=:

可见一个汉字在oracle中是占用了两个字节的

英文字母或符号只占用一个字节

Char()最多可存放个汉字

§ varchar

是一种变长的字符类型最多可占用字节的存储空间

创建一个表只有一列类型为varchar长度为

SQL> create table test_varchar( col varchar());

Table created

插入一些数据

SQL> insert into test_varchar values(a);

row inserted

SQL> insert into test_varchar values(aa);

row inserted

SQL> insert into test_varchar values(aaa);

row inserted

SQL> insert into test_varchar values(aaaaaaaaaa);

row inserted

SQL> insert into test_varchar values(aaaaaaaaaaa);

用dump函数查看每一行的内部存储结构

SQL> select col dump(col) from test_varchar;

COL DUMP(COL)

a Typ= Len=:

aa Typ= Len=:

aaa Typ= Len=:

aaaaaaaaaa Typ= Len=:

Typ=说明varchar类型在oracle中的类型编号为

Len代表了每一行数据所占用的字节数

后面是具体的存储值

由此可见varchar是存多少就占用多少空间比较节省空间的不会像char那样用空格填充

§ byte 和char

g中字符类型的宽度定义时可以指定单位

Byte就是字节

Char就是字符

Varchar( byte) 长度为个字节

Varchar( char) 长度为个字符所占的长度

Char( byte)长度为个字节

Char( char) 长度为个字符所占的长度

一个字符占用多少个字节是由当前系统采用的字符集来决定的

如一个汉字占用两个字节

查看当前系统采用的字符集

SQL> select * from nls_database_parameters where parameter =NLS_CHARACTERSET;

PARAMETER VALUE

NLS_CHARACTERSET ZHSGBK

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

采用char为单位的好处是使用多字节的字符集

比如在ZHSGBK字符集中一个汉字占用两个字节

把数据表的某一列长度定义为可存放个汉字通过下面的定义就可以了

Create table test_varchar(col_char varchar( char));

这样相对简单一些在数据库表设计时需要注意

继续实验新建一个表包含两列一列采用byte为单位一列采用char为单位

SQL> create table test_varchar (col_char varchar( char)col_byte varchar( byte));

Table created

Col_char列定义为可存放个字符

Col_byte 列定义为可存放个字节的字符

当前的系统采用字符集为ZHSGBK所以一个字符占两个字节

试着在表中插入一些数据

SQL> insert into test_varchar values(aa);

row inserted

SQL> insert into test_varchar values(a);

row inserted

SQL> insert into test_varchar values(袁袁袁袁袁袁袁袁袁袁aaaaaaaaaa);

row inserted

SQL> insert into test_varchar values(袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁);

insert into test_varchar values(袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁袁)

ORA: value too large for column PUB_TESTTEST_VARCHARCOL_BYTE (actual: maximum: )

第一次 在两列中都插入字符a

第二次 在col_char列插入字符在col_byte插入字符a

第三次 在col_char列中插入个中文字符在col_byte插入个字符a

第四次 在两列中都插入中文字符报错了第二列长度不够

再看看每一行的存储结构

SQL> select col_char dump(col_char) from test_varchar;

COL_CHAR DUMP(COL_CHAR)

a Typ= Len=:

袁 Typ= Len=:

袁袁袁袁袁袁袁袁袁袁 Typ= Len=:

当我们在col_char列插入个汉字时它的长度为

尽管我们在定义的时候是采用varchar(char)

由此可见oracle是根据当前数据库采用的字符集每个字符的所占字节数 X 字段长度来决定了该字段所占的字节数

在本例中varchar(char)相当于varchar()

不信我们可以试试看

SQL> desc test_varchar;

Name Type Nullable Default Comments

COL_CHAR VARCHAR() Y

COL_BYTE VARCHAR() Y

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

当不知道当前数据库采用的字符集一个字符占用多少字节时可以使用lengthb函数

SQL> select lengthb() from dual;

LENGTHB()

§ char还是varchar

新建一个表一列为char类型一列为varchar类型

SQL> create table test_char_varchar(char_col char()varchar_col varchar());

Table created

向该表中的两列都插入相关的数据

SQL> insert into test_char_varchar values(Hello WorldHello World);

row inserted

SQL> select * from test_char_varchar;

CHAR_COL VARCHAR_COL

Hello World Hello World

以char_col列为条件查询

SQL> select * from test_char_varchar where char_col =Hello World;

CHAR_COL VARCHAR_COL

Hello World Hello World

以varchar_col列为条件查询

SQL> select * from test_char_varchar where varchar_col =Hello World;

CHAR_COL VARCHAR_COL

Hello World Hello World

似乎char 和varchar类型没有什么两样再看看下面的语句

SQL> select * from test_char_varchar where varchar_col =char_col;

CHAR_COL VARCHAR_COL

这已经看出他们并不一样这涉及到字符串比较的问题

因为已经发生了隐式转换在与char列char_col进行比较时char_col列的内容已经转换成了char()在Hello World后面以空格进行填充了而varchar_col列并没有发生这种转换

如果要让char_col列与varchar_col列相等有两种方法

第一种是使用trim把char_col列的空格去掉

第二种是使遥rpad把varchar_col列用空格进行填充长度为的字符

SQL> select * from test_char_varchar where trim(char_col) = varchar_col;

CHAR_COL VARCHAR_COL

Hello World Hello World

SQL> select * from test_char_varchar where char_col = rpad(varchar_col);

CHAR_COL VARCHAR_COL

Hello World Hello World

如果使用trim函数如果char_col列上有索引那么索引将不可用了

此外还会在绑定变量时出现问题

上一篇:Windows下常见Oracle服务介绍

下一篇:Oracle跨版本导出EXP-00003错误的解决