Oracle的数据类型介绍
本文简要介绍 Oracle 常用的基本数据类型及特点,包括字符类型、LOB 类型、数值类型、日期类型。
1 字符类型
字符类型是 Oracle 中基础数据类型之一,也是数据库开发中最常用的一种数据类型。
Oracle 提供了四种主要的字符类型:char、nchar、varchar2、nvarchar2。
1.1 char 和 varchar2
char 最大长度为 2000 字节,属于定长度类型,即 char(n)指定了字符串长度,n 介于 1 到 2000 之间,即使输入的字节数小于 n,也会用空格补足到 n 长度。例如:
1 | l_char char(10):='test'; |
指定 l_char 的长度为 10,内容为“test”,但实际 l_char 存储的是“test”+六个空格。
varchar2 最大长度为 4000 字节,属于变长度类型,即 varchar2(n)指定了字符串长度,n 介于 1 到 4000 之间,如果输入的字节数小于 n,那么字符串长度等于实际输入长度。例如:
1 | l_varchar2 varchar2(10):='test'; |
指定 l_varchar2 的长度为 10,内容为“test”,实际 l_varchar2 存储的也是四个字节的“test”。
很明显,varchar2 要更节省数据库空间,但为什么还要有 char 类型呢?因为 char 的定长度特性,在需要频繁修改的字段,使用 char 具有一定的效率优势。
char 牺牲空间,提高效率,但有一个弊端,在读取 char 数据时,需要用 trim()函数来去掉 char 补足的空格,否则获取的就是带着一串空格的内容。
1.2 nchar 和 nvarchar2
在学习了 char 和 varchar2 后,nchar 和 nvarchar2 就不难理解了。
以 nchar 为例,在 char 前加了一个“n”,所代表的意义就是以字符数确定长度,而非以字节数确定长度。例如:
1 | l_char char(10):='1234567890'; |
1 | l_nchar nchar(10):='一二三四五六七八九零'; |
l_char 指定的长度是 10 个字节,那么它只能存储不超过 10 个的数字、英文字母、英文符号,或者不超过 5 个的汉字或符号(这里指 GBK 编码,一个汉字两个字节,如果是 UTF-8 编码,则是一个汉字占三个字节)。
l_nchar 指定的长度是 10 个字符,那么它可以存储不超过 10 个的数字、英文字母、英文符号、汉字或符号。
nvarchar2 和 nchar 类似,是以字符数来确定长度的,二者适合存储汉字或符号。
与 char 和 varchar2 相同的是,nchar 和 nvarchar2 的最大长度分别是 2000 字节和 4000 字节。那么在 GBK 编码下,nchar(n)中的 n 最大是 1000,nvarchar2(n)中的 n 最大是 2000,否则就有可能超出字节限制,导致数据丢失。在 UTF-8 编码下,其最大字符长度则分别为 666 和 1333。
1.3 varchar2,4000 还是 32767?
在 PL/SQL 中,有时会见到类似如下语句:
1 | l_varchar2 varchar2(32767); |
有的同学会有疑问:前边不是说 varchar2 最大长度是 4000 字节吗?
这并不矛盾,4000 字节的长度限制,是存储在数据表中的 varchar2 字段的最大长度。
在 PL/SQL 的存储过程中,varchar2 类型变量的最大长度可达 32767 字节!
表字段 4000 字节,存储过程变量 32767 字节,不能更长了。
2 LOB 类型
在存储二进制数据时,要使用 BLOB 类型;
存储超过 4000 字节的字符型表字段,或使用超过 32767 字节的 PL/SQL 变量时,需要用到 CLOB 类型,CLOB 可以存储不超过 4GB 的字符内容。
注意:在非必要的情况下,尽量不使用 BLOB 或 CLOB,它会大大降低执行效率。
3 字符类型
3.1 NUMBER(P,S)
NUMBER(P,S)是最常见的数字类型,需要 1~22 字节(BYTE)不等的存储空间,可以存放数据范围为:
10^-130~10^126(不包含此值)
P 是 Precison 的英文缩写,即精度缩写,表示有效数字的位数,最多不能超过 38 个有效数字。
S 是 Scale 的英文缩写,可以使用的范围为-84~127。Scale 为正数时,表示从小数点到最低有效数字的位数,它为负数时,表示从最大有效数字到小数点的位数。
下面是官方文档的示例:
实际数据 | 定义类型 | 存储数据 |
---|---|---|
123.89 | NUMBER | 123.89 |
123.89 | NUMBER(3) | 124 |
123.89 | NUMBER(6,2) | 123.89 |
123.89 | NUMBER(6,1) | 123.9 |
123.89 | NUMBER(3) | 124 |
123.89 | NUMBER(4,2) | 超出精度,无法存储 |
123.89 | NUMBER(6,-2) | 100 |
.01234 | NUMBER(4,5) | .01234 |
.00012 | NUMBER(4,5) | .00012 |
.000127 | NUMBER(4,5) | .00013 |
.0000012 | NUMBER(2,7) | .0000012 |
.00000123 | NUMBER(2,7) | .0000012 |
1.2e-4 | NUMBER(2,5) | 0.00012 |
1.2e-5 | NUMBER(2,5) | 0.00001 |
3.2 INTEGER 类型
INTEGER 是 NUMBER 的子类型,它等同于 NUMBER(38,0),用来存储整数。
INTEGER 的数值范围是-2147483648 到 2147483647 。
若 INTEGER 字段插入、更新的数值有小数,则会被四舍五入。
4 日期类型
DATE 是最常用的日期数据类型(本文不介绍 timestamp 相关内容),存储日期和时间信息。
DATE 类型可以转换成字符类型:
1 | to_char(DATE,'YYYY/MM/DD HH24:MI:SS') |
转换成类似’2018/01/29 22:13:42’的格式。
格式是可以自己定义的,也可以用:
1 | to_char(DATE,'YYYY-MM-DD') |
转换成类似’2018-01-29’的格式。
如果将 DATE 类型不经转换直接写入 VARCHAR2 字段,其格式是不可预知的,例如:
1 | update tableA set varcharA=sysdate; |
其中 varcharA 是 VARCHAR2 类型,sysdate 是 DATE 类型的系统当前时间,写入后,varcharA 字段可能是 2018-01-29 的格式,也可能是 29-1 月-18 的格式,可能是 Jan-29-18 的格式。
为了避免这种不可控,应使用 to_char 转换后再写入 VARCHAR2 字段:
1 | update tableA set varcharA=to_char(sysdate,'YYYY-MM-DD'); |
同样,VARCHAR2 类型也可以通过 to_date 函数转换为 DATE 类型:
1 | to_date('2018/01/29','YYYY-MM-DD') |
转换成 2018 年 1 月 29 日 0 时 0 分 0 秒的 DATE 类型。
总之,DATE 类型包含的数据,包含年月日时分秒,它可以通过不同的形式显示出来,但它是精确到秒的一个特定的时间点。