购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.3 数值类型

数值类型是最常用的几种数据类型之一,分为整型、浮点型、精确小数等类型,本节将详细讲解它们的使用方法。

5.3.1 数值类型介绍

PostgreSQL中的所有数值类型及其介绍见表5-4。

表5-4 数值类型列表

后面会对这些数值类型进行详细的讲解。

5.3.2 整数类型

整数类型有3种:smallint、int、bigint,注意,PostgreSQL中没有MySQL中的tinyint(1字节)、mediumint(3字节)这两种类型,也没有MySQL中的unsigned类型。

常用的数据类型是int(或integer),因为它提供了在范围、存储空间、性能之间的最佳平衡。一般只有在磁盘空间紧张的时候才使用smallint类型。通常,只有integer类型的取值范围不够时才使用bigint类型,因为前者的执行速度绝对快得多。

SQL只声明了整数类型integer(或int)和smallint。int与integer和int4是等效的,int2与smallint是等效的,bigint与int8是等效的。

5.3.3 精确的小数类型

精确的小数类型可用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,则表示创建一个可以存储任意精度和标度的数值(当然不能超过系统可以实现的精度和标度),这种类型的字段不会把输入数值转化成任何特定的标度,而带有标度声明的NUMERIC字段会把输入值转化为指定标度。在标准SQL和MySQL中,语法DECIMAL等价于DECIMAL(M,0),M在MySQL中默认为10,PostgreSQL中因作用不大而把它改成了一个任意精度和标度的数值。如果你关心可移植性,建议总是明确声明精度和标度。代码如下:


osdba=# create table t1(id1 numeric(3),id2 numeric(3,0),id3 numeric(3,2),id4 numeric);
CREATE TABLE
osdba=# \d t1
         Table "public.t1"
 Column |     Type     | Modifiers 
--------+--------------+-----------
 id1    | numeric(3,0) | 
 id2    | numeric(3,0) | 
 id3    | numeric(3,2) | 
 id4    | numeric      | 
osdba=# insert into t1 values(3.1,3.5,3.123,3.123);
INSERT 0 1
osdba=# select * from t1;
 id1 | id2 | id3  |  id4  
-----+-----+------+-------
   3 |   4 | 3.12 | 3.123
(1 row) 
osdba=# insert into t1 values(3.1,3.5,13.123,3.123);
ERROR:  numeric field overflow
DETAIL:  A field with precision 3, scale 2 must round to an absolute value less than 10^1.
STATEMENT:  insert into t1 values(3.1,3.5,13.123,3.123);
ERROR:  numeric field overflow
DETAIL:  A field with precision 3, scale 2 must round to an absolute value less than 10^1.

从上面的代码中可以看到,若字段声明了标度,超过小数点位数的标度会自动4舍5入后进行存储。而对于既没有声明精度也没有声明标度的number类型来说,则会原样存储。

对于声明了精度的数值,如果INSERT语句插入的数值超出声明的精度范围,则会报错。

5.3.4 浮点数类型

数据类型real和double precision是不精确的、变精度的数字类型。

对于浮点数,需要注意如下几个方面:

·如果要求精确地计算(比如计算货币金额),应使用numeric类型。

·如果想用这些类型做任何重要的复杂计算,尤其是那些对范围情况(无穷/下溢)严重依赖的复杂计算,那么应该仔细评诂你的实现。

·对两个浮点数值进行相等性比较时,有可能不会像你所想象的那样运转。

除了普通的数字值之外,浮点类型还有以下几个特殊值:

·Infinity。

·-Infinity。

·NaN。

这些值分别表示特殊值“正无穷大”“负无穷大”“不是一个数字”。在不遵循IEEE 754浮点算术的机器上,这些值的含义可能不是预期的。如果在SQL命令里把这些数值当作常量来写,必须在它们周围放上单引号,如“UPDATE table SET x='Infinity'”。输入时,这些值与大小写无关。

5.3.5 序列类型

在序列类型中,serial和bigserial与MySQL中的自增字段含义相同。PostgreSQL实际上是通过序列(sequence)实现的。PostgreSQL数据库与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 t.id;

5.3.6 货币类型

货币类型可以存储固定小数的货币数目,与浮点数不同,它是完全保证精度的。其输出格式与参数lc_monetary的设置有关,不同的国家其货币输出格式也不相同,示例如下:


osdba=# SELECT '12.34'::money;
    money  
---------
  ¥12.34
(1 row)

osdba=# show lc_monetary;
  lc_monetary 
-------------
  zh_CN.UTF-8
(1 row)

osdba=# set lc_monetary = 'en_US.UTF-8';
SET
osdba=# SELECT '12.34'::money;
  money  
--------
  $12.34
(1 row)

从上面的例子中可以看出,如果是中文,输出的是“¥12.34”,如果是英文(美国),则输出为“$12.34”。

money类型占用8字节空间来存储数据,表示的范围为-92233720368547758.08到+92233720368547758.07。

5.3.7 数学函数和操作符

PostgreSQL支持丰富的数学操作符,具体见表5-5。

表5-5 数学操作符

表5-6和表5-7中列出了可用的数学函数。其中,“dp”表示double precision。所列函数中,许多都有多种不同的形式,不同形式的区别在于参数不同。除非特别指明,任何特定形式的函数都会返回和它的参数相同的数据类型。处理double precision数据的函数大多是在宿主系统的C库的基础上实现的。因此,精度和数值范围方面的行为都是根据宿主系统的不同而变化的。

表5-6 数学函数

表5-7 数学函数之三角函数 mBd4hSB+R0nlEpoW+kWtbVgLe6ghYp2MiAPlpHxHjhifaSIjCUzAlLwCbqss8b9B

点击中间区域
呼出菜单
上一章
目录
下一章
×