postgresql12中支持的基本数字数据类型如下:
| Name | Storage Size | Description | Range |
|---|---|---|---|
| smallint | 2 bytes | small-range integer | -32768 to +32767 |
| integer | 4 bytes | typical choice for integer | -2147483648 to +2147483647 |
| bigint | 8 bytes | large-range integer | -9223372036854775808 to +9223372036854775807 |
| decimal | variable | user-specified precision, | exact up to 131072 digits before the decimal point; up to 16383 digits after the decimal point |
| numeric | variable | user-specified precision, | exact up to 131072 digits before the decimal point; up to 16383 digits after the decimal point |
| real | 4 bytes | variable-precision, inexact | 6 decimal digits precision |
| double precision | 8 bytes | variable-precision, inexact | 15 decimal digits precision |
| smallserial | 2 bytes | small autoincrementing integer | 1 to 32767 |
| serial | 4 bytes | autoincrementing integer | 1 to 2147483647 |
| bigserial | 8 bytes | large autoincrementing integer | 1 to 9223372036854775807 |
一般从其他数据库迁移过来,需要考虑数据类型如何映射,用的比较多的数据类型有 integer、numeric、double precision,这三种数据类型的除了精度不一样,还需要考虑性能差异,下面来测试一下这三个数据类型的性能情况
创建测试函数
create or replace function compute_integer()returns integer as $$
declare
num integer:=0;
begin
for i in 1..10000 loop
num=num+i;
end loop;
return num;
end;
$$language plpgsql;
create or replace function compute_double()returns double precision as $$
declare
num double precision:=0.0;
begin
for i in 1..10000 loop
num=num+i;
end loop;
return num;
end;
$$language plpgsql;
create or replace function compute_numeric() returns numeric as $$
declare
num numeric:=0.0;
begin
for i in 1..10000 loop
num=num+i;
end loop;
return num;
end;
$$language plpgsql;
运行测试函数
pg=> explain analyze select compute_integer();
QUERY PLAN
------------------------------------------------------------------------------------
Result (cost=0.00..0.26 rows=1 width=4) (actual time=3.745..3.748 rows=1 loops=1)
Planning Time: 0.033 ms
Execution Time: 3.784 ms
(3 rows)
pg=> explain analyze select compute_double();
explain analyze select compute_numeric(); QUERY PLAN
------------------------------------------------------------------------------------
Result (cost=0.00..0.26 rows=1 width=8) (actual time=7.197..7.204 rows=1 loops=1)
Planning Time: 0.155 ms
Execution Time: 7.262 ms
(3 rows)
pg=> explain analyze select compute_numeric();
QUERY PLAN
---------------------------------------------------------------------------------------
Result (cost=0.00..0.26 rows=1 width=32) (actual time=18.275..18.286 rows=1 loops=1)
Planning Time: 0.048 ms
Execution Time: 18.517 ms
(3 rows)
性能差异还是比较巨大的。但是int一般存储整数,double precision 存在精度丢失的问题,numeric则精度准确。存在肯定是有道理的,面对现在粗放的开发生态环境,细致研究往往会有事半功倍的效果。
double precision 和 numeric 支持一个特殊的数值 NaN,这个值的意思是不是一个数字,但是其本身是可以跟数值进行比较的,其值大于任何数值,同时也可以和本身相等,测试如下:
pg=> create table pg_t(id numeric);
pg=> insert into pg_t values(1),(2),('NaN'),(-1),(-2),(0);
pg=> select id,case when id > 'NaN' then 'Greater' when id < 'NaN' then 'Lesser' else 'Equal' end from pg_t;
id | case
-----+--------
1 | Lesser
2 | Lesser
NaN | Equal
-1 | Lesser
-2 | Lesser
0 | Lesser
double precision 比 numeric 多了两个特殊数值 Infinity 、-Infinity分别表示正无穷大和负无穷大,测试方法不再赘述。
serial 这类数据类型,类似于 mysql自增列,在使用的时候默认创建了 tablename_colname_seq的索引,测试如下:
pg=> create table pg_t(id serial,item varchar );
pg=> insert into pg_t values(default,'1');
pg=> insert into pg_t(item) values('2');
pg=> select * from pg_t;
id | item
----+------
1 | 1
2 | 2
pg=> \d pg_t_id_seq
Sequence "pg.pg_t_id_seq"
Type | Start | Minimum | Maximum | Increment | Cycles? | Cache
---------+-------+---------+------------+-----------+---------+-------
integer | 1 | 1 | 2147483647 | 1 | no | 1
Owned by: pg.pg_t.id
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




