postgresql的数据类型很多,也可以使用create type命令创建自定义数据类型,但常用的数据类型是以下三种:
l 数字数据类型
l 字符串数据类型
l 日期/时间数据类型
数字数据类型
数字数据类型用于指定表中的数字数据,详情如下表所示:
名称 | 描述 | 存储大小 | 范围 |
smallint | 存储整数,小范围 | 2字节 | -32768 至 +32767 |
integer | 存储整数。使用这个类型可存储典型的整数 | 4字节 | -2147483648 至 +2147483647 |
bigint | 存储整数,大范围。 | 8字节 | -9223372036854775808 至 9223372036854775807 |
用户指定的精度,精确 | 变量 | 小数点前最多为131072个数字; 小数点后最多为16383个数字。 | |
numeric | 用户指定的精度,精确 | 变量 | 小数点前最多为131072个数字; 小数点后最多为16383个数字。 |
real | 可变精度,不精确 | 4字节 | 6位数字精度 |
double precision | 可变精度,不精确 | 8字节 | 15位数字精度 |
smallserial | 自动递增的小整数 | 2字节 | 1至32767 |
serial | 自动递增整数 | 4字节 | 1 至 2147483647 |
bigserial | 大的自动递增整数 | 8字节 | 1 至 9223372036854775807 |
数字类型又可以分为四类
1. 整数类型
类型smallint、integer、bigint只能保存整数,也就是没有小数部分。如果试图在整数类型中保存超过范围的整数,数据库将会报错。例:
mydb=# INSERT into test VALUES(32767);
INSERT 0 1
mydb=# INSERT into test VALUES(32768);
ERROR: smallint out of range
mydb=# SELECT * from test;
smallint1
———–
32767
(1 row)
2. 任意精度数值
numeric类型最多能存储有1000个数字位的数字并且能进行准确的数值计算。它主要用于需要准确地表示数字的场合,如货币金额。不过,对numeric 类型进行算术运算比整数类型和浮点类型要慢很多。
numeric类型有两个术语,分别是标度和精度。numeric类型的标度(scale)是到小数点右边所有小数位的个数, numeric 的精度(precision)是所有数字位的个数,例如,23.5141 的精度是6而标度为4。可以认为整数的标度是零。
numeric 类型的最大精度和最大标度都是可以配置的。可以用下面的语法定义一个numeric类型:
a) NUMERIC(precision, scale)
b) NUMERIC(precision)
c) NUMERIC
精度必须为正数,标度可以为零或正数。在上面的第二种语法中没有指定标度,则系统会将标度设为0,所以NUMERIC(precision,0)和NUMERIC(precision)是等价的。第三种类型的语法没有指定精度和标度,则这种类型的列可以接受任意精度和标度的numeric数据(在系统能表示的最大精度范围内),而不会对输入的数据进行精度或标度的变换。如果一个列被定义成numeric类型而且指定了标度,那么输入的数据将被强制转换成这个标度(如果它的标度比定义列的numeric的标度大),进行标度转换时的规则是四舍五入。如果输入的数据进行标度转换后得到的数据在小数点左边的数据位的个数超过了列的类型的精度减去标度的差,系统将会报错。例:
—构建环境
CREATE TABLE test (numeric1 numeric(3,3));
—插入超过精度和标度的值
INSERT into test VALUES(1.3456);
—报错信息
ERROR: numeric field overflow
DETAIL: A field with precision 3, scale 3 must round to an absolute value less than 1.
—插入超过标度的值,超过标度的部分被四舍五入成小于1的数。
INSERT into test VALUES(0.3455);
INSERT into test VALUES(0.3454);
SELECT * from test;
numeric1
———-
0.346
0.345
numeric 类型可以接受一个特殊的值 “NaN” (Not a Number),它的意思是“不是一个数字“。任何在 NaN 上面的操作都生成另外一个 NaN。 如果在 SQL 命令里把这些值当作一个常量写,必须把它用单引号引起来,比如 UPDATE table SET x = ‘NaN‘。在输入时,”NaN”的大小写无关紧要。例:
INSERT into test values(‘NaN‘);
SELECT * from test;
numeric1
———-
0.346
0.345
NaN
注意:在其它的数据库中,NaN和任何的数值数据都不相等,两个NaN也是不相等的,在postgresSQL中,为了允许numeric值可以被排序和使用基于树的索引,PostgreSQL把NaN值视为相等,并且比所有非NaN值都要大。例:
SELECT * from test where numeric1=’NaN‘;
numeric1
———-
NaN
SELECT * from test t1,test t2 where t1.numeric1=t2.numeric1;
numeric1 | numeric1
———-+———-
0.345 | 0.345
0.346 | 0.346
NaN | NaN
SELECT * from test where NUMERIC1>10;
numeric1
———-
NaN
3. 浮点类型
数据类型 real 和 double precision 表示不准确的变精度的数字。不准确意味着一些值不能准确地转换成内部格式并且是以近似的形式存储的,存储在数据库里的只是它们的近似值。如果要求准确地保存某些数值(比如计算货币金额),应使用 numeric 类型。另外,比较两个浮点数是否相等时,可能会得到意想不到的结果。例:
create table test(real1 real)
insert into test VALUES(1.6666666);
insert into test VALUES(1.666666);
insert into test VALUES(1.66666);
SELECT * FROM test;
real1
———
1.66667
1.66667
1.66666
(3 rows)
mydb=# SELECT * from test where real1=1.66666; —等值运算未能获取到想要的数据
real1
——-
(0 rows)
mydb=# SELECT * from test where real1=1.66667; —等值运算未能获取到想要的数据
real1
——-
(0 rows)
mydb=# SELECT * from test where real1>1.66666;
real1
———
1.66667
1.66667
(2 rows)
mydb=# SELECT * from test where real1>1.6666;
real1
———
1.66667
1.66667
1.66666
(3 rows)
浮点类型还有几个特殊值:Infinity、-Infinity、NaN。这些值分别表示 IEEE 754标准中的特殊值“正无穷大“,“负无穷大“, 以及“不是一个数字“。如果在 SQL 命令里把这些数值当作常量写,必须在它们用单引号引起来,例如UPDATE table SET x = ‘Infinity’。 输入时,这些值的大小写无关紧要。
PostgreSQL 还支持 SQL 标准中定义的类型float和float(p)。p 定义以二进制位表示的最低可以接受的精度,p的取值在1到53之间。实际上,如果p的取值在1到24之间,float(p)被看成是real类型,如果p的取值在25到53之间,float(p)被看成是double precision类型。不带精度的float被看成是double precision类型。
4. Postgresql的序列
Postgresql中的序列作为数据类型存在,smallserial、serial和bigserial并不是真正的类型,只是为了创建唯一标识符而存在的符号。
创建序列的两种方式
1、直接在表中指定字段类型为smallserial、serial和bigserial。
CREATE table test(text varchar,serial1 serial);
INSERT into test VALUES(‘一‘);
INSERT into test VALUES(‘二‘);
INSERT into test VALUES(‘三‘);
INSERT into test VALUES(‘四‘);
mydb=# Select * from test;
text | serial1
——+———
一 | 1
二 | 2
三 | 3
四 | 4
(4 rows)
2、先创建序列名称,然后在新建表中指定相关列的属性,该列需要int类型。
序列创建语法
CREATE [ TEMPORARY | TEMP ] SEQUENCE name [ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { table.column | NONE } ]
例:
—创建一个步长为10,最小值为1,初始值为17,缓存为100,可循环的使用的序列
create sequence test_id_seq increment by 10 minvalue 1 no maxvalue start with 17 cache 100 cycle;
—查看序列的属性,两种方式,使用psql中\d查看,或直接查询序列名称
mydb=# \d test_id_seq
Sequence “public.test_id_seq”
Column | Type | Value
—————+———+———————
sequence_name | name | test_id_seq
last_value | bigint | 17
start_value | bigint | 17
increment_by | bigint | 10
max_value | bigint | 9223372036854775807
min_value | bigint | 1
cache_value | bigint | 100
log_cnt | bigint | 0
is_cycled | boolean | t
is_called | boolean | f
mydb=# SELECT * from test_id_seq;
sequence_name | last_value | start_value | increment_by | max_value | min_value | cache_value | log_cnt | is_cycled | is_called
—————+————+————-+————–+———————+———–+————-+———+———–+———–
test_id_seq | 1007 | 17 | 10 | 9223372036854775807 | 1 | 100 | 32 | t | t
(1 row)
—创建一个使用上述序列的表
create table test(wenzi varchar,id int4 not null DEFAULT nextval(‘test_id_seq‘));
—为表中不使用序列的列插入数据
INSERT into test VALUES(‘一‘);
INSERT into test VALUES(‘二‘);
INSERT into test VALUES(‘三‘);
INSERT into test VALUES(‘四‘);
—查询插入后的数据
mydb=# select * from test;
wenzi | id
——-+—-
一 | 17
二 | 27
三 | 37
四 | 47
(4 rows)