数值类型是最常用的几种数据类型之一,主要分为:
- 整型
- 浮点型
- 精确小数
数值类型介绍
类型名称 | 存储空间 | 描述 | 范围 |
---|---|---|---|
smallint | 2字节 | 小范围的整数。Oracle中没有此数值类型,使用number代替 | -2^15 ~ 2^15-1 |
int 或 integer | 4字节 | 常用的整数。Oracle中integer等同于number(38),与此类型的意义不同 | -2^31 ~ 2^31-1 |
bigint | 8字节 | 大范围的整数。Oracle中没有此数值类型,使用number代替 | -2^63 ~ 2^63-1 |
numeric或decimal | 变长 | 用户声明的精度,精确。注意,Oracle中叫number,与PG中的名称不一样 | 不限制 |
real | 4字节 | 变精度,不精确 | 6位十进制数字精度 |
double precision | 8字节 | 变精度,不精确 | 15位十进制数字精度 |
serial | 4字节 | 自增整数 | 1~2^31-1 |
bigserial | 8字节 | 大范围的自增整数 | 1~2^63-1 |
整数类型
整数类型有三种:
- smallint
- int
- bigint
注意:PG中没有MySql中的tinyint(1字节)、mediumint(3字节)这两种类型,也没有MySql中的unsigned类型。
常用的数据类型是int(或integer),因为它提供了在范围、存储空间、性能之间的最佳平衡。一般只有在磁盘空间紧张的时候才使用smallint类型。通常,只有integer类型的取值范围不够时才使用bigint类型,因为前者的执行速度绝对快得多。
SQL只声明了整数类型integer或int和smallint。
- int与integer和int4是等效的
- smallint与int2是等效的
- bigint与int8是等效的
精确的小数类型
- numeric
- numeric(m,n)
- numeric(m)
numeric与decimal类型是等效的,这两种类型都是SQL标准,可以存储最多1000位精度的数字,并且可准确地进行计算。==它们特别适用于货币金额和其他要求精确计算的场合。==不过,基于numeric类型的算术运算相比于基于整数类型或者下面介绍的浮点数类型的算术运算,其速度要慢很多。
如果要声明一个字段的类型是numeric,可以用下面的语句:
NUMERIC(precision,scale)
其中,精度precision必须为正数,标度scale可以为0或者正数。
NUMERIC(precision)表示标度为0,与NUMERIC(precision,0)的含义是相同的。
如果不带任何精度和标度地声明NUMERIC,则表示创建一个可以存储任意精度和标度的数值(当然不能超过系统可以实现的精度和标度)
在标准SQL和MySql中,语法DECIMAL等价于DECIMAL(M,0),M在MySql中默认为10,PG中因作用不大而把它改成了一个任意精度和标度的数值。如果你关心移植性,建议总是明确声明精度和标度
create table t1(id1 numeric(3),id2 numeric(3,0),id3 numeric(3,2),id4 numeric);
insert into t1 values(3.1,3.5,3.123,3.123);
select * from t1;
insert into t1 values(3.1,3.5,13.123,3.123);
- 若字段声明了标度,超过小数点位数的标度会自动四舍五入后进行存储
- 没有声明精度也没有声明标度地numeric类型,会原样存储
- 声明了精度的数值,如果INSERT语句插入的数值超出声明的精度范围,则会报错
浮点数类型
数据类型real和double precision是不精确的、变精度的数字类型。
浮点数需要注意以下几个方面:
- 如果要求精确地计算(比如计算货币金额),应使用nmeric类型
- 如果想用这些类型做任何重要的复杂计算,尤其是那些对范围情况(无穷/下溢)严重依赖的复杂计算,应该仔细评估你的实现
- 对两个浮点数值进行相等性比较时,有可能不会像你所想象的那样运转
除了普通的数字值之外,浮点类型还有以下几个特殊值:
- Infinity:正无穷大
- -Infinity:负无穷大
- NaN:不是一个数字
这些值的含义可能不是预期的,如果在SQL命令里把这些数值当作常量来写,必须在它们周围放上单引号,如:“UPDATE table SET x=‘Infinity’”。输入时,这些值与大小无关
序列类型
在序列类型中,serial和bigserial与MySQL中的自增字段含义相同
PG实际上通过序列(sequence)实现的。PG数据库与Oracle一样有序列,而MySQL中没有序列,示例如下:
create table t(id SERIAL);
等价于
create sequence t_id_seq;
create table t(
id integer not null default nextval('t_id_seq')
);
alter sequence t_id_seq owned by tt.id;
货币类型
货币类型可以存储固定小数的货币数目,与浮点数不同,它是完全保证精度的。其输出格式与参数lc_monetary的设置有关,不同的国家其货币输出格式也不相同,示例如下:
select '12.32'::money;
show lc_monetary;
set lc_monetary = 'en_US';
select '12.32'::money;
money类型占用8字节空间来存储数据,表示的范围为-92233720368547758.08到+92233720368547758.07