GaussDB(DWS)数据类型之数值类型

举报
sincatter 发表于 2021/06/24 20:25:30 2021/06/24
【摘要】 数值类型在数据库的计算中使用量极大,考虑到存储占用、精度要求等原因,数值类型会分为多种形式,这里有必要对数据类型进行总结。

数值类型在数据库的计算中使用量极大,考虑到存储占用、精度要求等原因,数值类型会分为多种形式,这里有必要对数据类型进行总结。

整型数据

名称 描述 存储空间 范围
TINYINT 微整数,别名为INT1。 1字节 0 ~ 255
SMALLINT 小范围整数,别名为INT2。 2字节 -32,768 ~ +32,767
INTEGER 常用的整数,别名为INT4。 4字节 -2,147,483,648 ~ +2,147,483,647
BINARY_INTEGER 常用的整数INTEGER的别名,为兼容Oracle类型。
BIGINT 大范围的整数,别名为INT8。 8字节 -9,223,372,036,854,775,808 ~ 9,223,372,036,854,775,807

如上所示,整数类型比较简单,包括tinyint、smallint、integer、bigint,只存储整数位,没有小数,如果输入类型的超出范围会报错处理。

postgres=# select 10000::tinyint;
ERROR:  tinyint out of range
CONTEXT:  referenced column: int1
postgres=# select 10000::int;
 int4  
-------
 10000
(1 row)

numeric类型

名称 描述 存储空间 范围
NUMERIC[(p[,s])], 精度p取值范围为[1,1000],标度s取值范围为[0,p]。 说明: p为总位数,s为小数位数。 每四位(十进制位)占用两个字节,然后在整个数据上加上八个字节的额外开销。 未指定精度的情况下,小数点前最大131,072位,小数点后最大16,383位。

numeric还存在一些别名,包括DECIMAL[(p[,s])]、NUMBER[(p[,s])]、DEC[(p[,s])]、INTEGER[(p[,s])]

postgres=# select 12.34::numeric(10,3);
 numeric 
---------
  12.340
(1 row)

postgres=# select 12.34::decimal(10,3);
 numeric 
---------
  12.340
(1 row)

postgres=# select 12.34::number(10,3);
 numeric 
---------
  12.340
(1 row)

postgres=# select 12.34::dec(10,3);
 numeric 
---------
  12.340
(1 row)

postgres=# select 12.34::integer(10,3);
 numeric 
---------
  12.340
(1 row)

numeric类型指定时,包含两个内容:精度precision和标度scale。

精度表示这个数的有效位有多少,必须是正数,标度则表示小数有多少位,可以是0或者正数。

postgres=# select 1.5::numeric(0,0);
ERROR:  NUMERIC precision 0 must be between 1 and 1000
LINE 1: select 1.5::numeric(0,0);
                    ^
CONTEXT:  referenced column: numeric
postgres=# select 1.5::numeric(5,-1);
ERROR:  NUMERIC scale -1 must be between 0 and precision 5
LINE 1: select 1.5::numeric(5,-1);
                    ^
CONTEXT:  referenced column: numeric
postgres=# select 1.5::numeric(5,0);
 numeric 
---------
       2
(1 row)

当输入的数值有效值比指定的精度低时,分两种情况:整数位超过精度,报错处理,小数位超过精度时,做四舍五入处理。

postgres=# select 12345.6789::numeric(3,1);
ERROR:  numeric field overflow
DETAIL:  A field with precision 3, scale 1 must round to an absolute value less than 10^2.
CONTEXT:  referenced column: numeric
postgres=# select 12345.6789::numeric(10,1);
 numeric 
---------
 12345.7
(1 row)

NaN是一个特殊的numeric值,表示不等于任何一个数,并且和其他数值做比较时,大于任意一个数。

postgres=# select 'NaN'::numeric > 100;
 ?column? 
----------
 t
(1 row)

postgres=# select 'NaN'::numeric < 100;
 ?column? 
----------
 f
(1 row)

postgres=# select 'NaN'::numeric = 100;
 ?column? 
----------
 f
(1 row)

numeric类型的一个重要特点是:存储空间可以根据指定精度进行扩展,精度可以达到很高。所以比较适合于一些精度要求高的场景,比如货币计算,有精度要求的科学计算等。但相对的因为存储空间的扩展和计算方式的实现相较固定精度存在差异,需要有额外的时间和空间消耗,在同等精度时,会比固定精度的计算慢上不少。

浮点类型

名称 描述 存储空间 范围
REAL,FLOAT4 单精度浮点数,不精准。 4字节 6位十进制数字精度。
DOUBLE PRECISION,FLOAT8 双精度浮点数,不精准。 8字节 1E-307~1E+308,15位十进制数字精度。
FLOAT[§] 浮点数,不精准。精度p取值范围为[1,53]。 说明: p为精度,表示总位数。 4字节或8字节 根据精度p不同选择REAL或DOUBLE PRECISION作为内部表示。如不指定精度,内部用DOUBLE PRECISION表示。
BINARY_DOUBLE 是DOUBLE PRECISION的别名,为兼容Oracle类型。

浮点类型根据精度区分为单精度和双精度,占用的存储空间有差异。

特殊浮点值正无穷Infinity,负无穷-Infinity,非数值NaN,同numeric的NaN一样,NaN不等于任何一个数,并且和其他数值做比较时,大于任意一个数。

postgres=# select * from (values (1.5::float),(-1.5::float),(0::float),('Infinity'::float),('-Infinity'::float),('NaN'::float)) v(x) order by x;
     x     
-----------
 -Infinity
      -1.5
         0
       1.5
  Infinity
       NaN
(6 rows)

浮点类型是一种不精确的数字存储方式,只能存储单精度或双精度的数值,在进行内部转换时可能存在近似存储的情况,所以在使用浮点数值是要考虑是否合适:

1.如果存储场景是一些对精度要求高的场景,可以考虑使用numeric类型;

2.如果使用浮点做一些计算时,可能出现无穷或者溢出的情况,需要对这些情况做特殊考虑;

3.类似于其他计算机语言,浮点数值做等值比较时,因为内部存储存在微小误差的存在,有可能结果不可靠,在做浮点类的等值运算时需要注意。

postgres=# select 1.1::float4::float8;
      float8      
------------------
 1.10000002384186
(1 row)

postgres=# select 1.1::float4=1.1;
 ?column? 
----------
 f
(1 row)

小结

对于数值对象,在定义具体类型和精度时,要考虑实际的业务,根据不同的场景合理定义数值类型,达到精度和存储空间的平衡。在使用浮点类型时,还要考虑运算是否会因为浮点类型存储机制的原因,而导致的计算误差,影响到业务结果。

想了解GuassDB(DWS)更多信息,欢迎微信搜索“GaussDB DWS”关注微信公众号,和您分享最新最全的PB级数仓黑科技,后台还可获取众多学习资料哦~

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。