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)