1
数字类型
数字类型由
2
、
4
或
8
字节的整数以及
4
或
8
字节的浮点数和可选精度小数组成。
数字类型常量的语法见
常量
。数字类型有一整套对应的数学操作符和函数。相关信息请参考
函数和操作符
。
下面的几节详细描述这些类型。
1.1
整数类型
类型
tinyint
、
smallint
、
integer
和
bigint
存储各种范围的全部是数字的数,也就是没有小数部
分的数字。试图存储超出范围以外的值将导致一个错误。
常用的类型是
integer
,因为它提供了在范围、存储空间和性能之间的最佳平衡。一般只有在磁盘空间紧
张的时候才使用
tinyint
或
smallint
类型。而只有在
integer
的范围不够的时候才使用
bigint
。
SQL
只声明了整数类型
integer
(或
int
)、
tinyint
、
smallint
和
bigint
。类型
int2
、
int4
和
int8
都是扩展,也在许多其它
SQL
数据库系统中使用。
7.1.2
任意精度数字
类型
numeric
可以存储非常多位的数字。我们特别建议将它用于货币金额和其它要求计算准确的数量。
numeric
值的计算在可能的情况下会得到准确的结果,例如加法、减法、乘法。不过,
numeric
类型上的
算术运算比整数类型或者下一节描述的浮点数类型要慢很多。
在随后的内容里,我们使用了下述术语:一个
numeric
的
precision
(精度)是整个数中有效位的总数,也
就是小数点两边的位数。
numeric
的
scale
(刻度)是小数部分的数字位数,也就是小数点右边的部分。因
此数字
23.5141
的精度为
6
而刻度为
4
。可以认为整数的刻度为零。
numeric
列的最大精度和最大比例都是可以配置的。要声明一个类型为
numeric
的列,你可以用下面的
语法:
NUMERIC(precision, scale)
精度必须为正数,比例可以为零或者正数。另外:
NUMERIC(precision)
选择比例为
0
。如果使用
NUMERIC
创建一个列时不使用精度或比例,则该列可以存储任何精度和比例的数字值,并且值的范围最多可以到实现
精度的上限。一个这种列将不会把输入值转化成任何特定的比例,而带有比例声明的
numeric
列将把输入
值转化为该比例(
SQL
标准要求缺省的比例是
0
,即转化成整数精度。我们觉得这样做有点没用。如果你关
心移植性,那你最好总是显式声明精度和比例)。
Note:
显式指定类型精度时的最大允许精度为
1000
,没有指定精度的
NUMERIC
受到表
1-1
中描述的限制所
控制。
如果一个要存储的值的比例比列声明的比例高,那么系统将尝试圆整(四舍五入)该值到指定的分数位数。
然后,如果小数点左边的位数超过了声明的精度减去声明的比例,那么抛出一个错误。
数字值在物理上是以不带任何前导或者后缀零的形式存储。因此,列上声明的精度和比例都是最大值,而不
是固定分配的(在这个方面,
numeric
类型更类似于
varchar(n
)
,而不像
char(n
)
)。实际存储要求是
每四个十进制位组用两个字节,
plus three to eight bytes overhead.
除了普通的数字值之外,
numeric
类型允许特殊值
NaN
,表示“不是一个数字”。任何在
NaN
上面的操作
都生成另外一个
NaN
。如果在
SQL
命令里把这些值当作一个常量写,你必须在其周围放上单引号,例如
UPDATE table SET x = 'NaN'
。在输入时,字串
NaN
被识别为大小写无关。
Note:
在“不是一个数字”概念的大部分实现中,
NaN
被认为不等于任何其他数字值(包括
NaN
)。为了允
许
numeric
值可以被排序和使用基于树的索引,
KingbaseES
把
NaN
值视为相等,并且比所有非
NaN
值
都要大。
类型
decimal
和
numeric
是等效的。两种类型都是
SQL
标准的一部分。
在对值进行圆整时,
numeric
类型会圆到远离零的整数,而(在大部分机器上)
real
和
double
precision
类型会圆到最近的偶数上。例如:
SELECT x,
round
(x::numeric) AS num_round,
round
(x::double precision) AS dbl_round
FROM generate_series(
-
3.5
,
3.5
,
1
)
as
x;
x
|
num_round
|
dbl_round
------+-----------+-----------
-
3.5
|
-
4
|
-
4
-
2.5
|
-
3
|
-
2
-
1.5
|
-
2
|
-
2
-
0.5
|
-
1
|
-
0
0.5
|
1
|
0
1.5
|
2
|
2
2.5
|
3
|
2
3.5
|
4
|
4
(
8
rows)
KingbaseES
同时也支持声明一个类型为
number
的列,你可以用下面的语法
NUMBER(precision, scale)
精度必须为正数。精度可以用‘
*
’号代替,表示默认精度
38
,比例可以为零、正数、负数,也可以大于精度
的值。
参数
ora_input_emptystr_isnull
被设置为
true
时可以使
number
数据类型接受空串,默认值为
false
。除介绍的外,
number
与
numberic
是等效的。
1.3
浮点类型
数据类型
real
和
double precision
是不准确的、变精度的数字类型。在所有当前支持的平台上,这
些类型是
IEEE
标准
754
二进制浮点算术(分别对应单精度和双精度)的实现,一直到下层处理器、操作系
统和编译器对它的支持。
不准确意味着一些值不能准确地转换成内部格式并且是以近似的形式存储的,因此存储和检索一个值可能出
现一些缺失。处理这些错误以及这些错误是如何在计算中传播的主题属于数学和计算机科学的一个完整的分
支,我们不会在这里进一步讨论它,这里的讨论仅限于如下几点:
•
如果你要求准确的存储和计算(例如计算货币金额),应使用
numeric
类型。
•
如果你想用这些类型做任何重要的复杂计算,尤其是那些你对范围情况(无穷、下溢)严重依赖的事
情,那你应该仔细评诂你的实现。
•
用两个浮点数值进行等值比较不可能总是按照期望地进行。
在所有当前支持的平台上,
real
类型的范围是在
-1E+37
到
+1E+37
之间,精度至少是
6
位小数。
double
precision
类型有
-1E+308
到
+1E+308
的范围,精度是至少
15
位数字。太大或者太小的值都会导致错误。
如果输入数字的精度太高,那么可能发生园整。太接近零的数字,如果无法与零值的表现形式相区分就会产
生下溢错误。
默认情况下
,
浮点值以文本形式输出最短的精确的十进制表示
;
产生的十进制值更接近真实的存储二进制值相
比于其他任何在相同的二进制值表示的精度。(然而
,
输出值目前没有完全精确地介于两个可表示的值之间
,
以避免一个普遍的错误
,
输入例程不适当尊重
round-to-even
规则。)这个值将使用
float8
类型值的最多
17
个重要的小数位数
,
以及
float4
值的最多
9
位数。
Note:
这种最精确的输出格式生成起来要比历史的四舍五入格式快得多。
为了与旧版本的
KingbaseES
生成的输出兼容,并允许降低输出精度,可以使用
extra_float_digits
参数来选择
rounded decimal
输出。将值设置为
0
将恢复先前的默认舍入值为
6(
对于
float4
)
或
15(
对于
float8
)
的有
效小数位数。设置为负值会进一步减少位数
;
例如
-2
将分别四舍五入输出为
4
位或
13
位。
extra_float_digits
大于
0
的任何值都选择最短精确格式。
Note:
以前,需要精确值的应用程序必须将
extra_float_digits
设置为
3
才能获得这些值。为了实现版本之间的
最大兼容性,它们应该继续这样做。
除了普通的数字值之外,浮点类型还有几个特殊值:
Infinity
-Infinity
NaN
这些值分别表示
IEEE 754
特殊值“正无穷大”、“负无穷大”以及“不是一个数字”。如果在
SQL
命令里把这
些数值当作常量写,你必须在它们周围放上单引号,例如
UPDATE table SET x = '-Infinity'
。在
输入时,这些串是以大小写无关的方式识别的。
Note:
IEEE754
指定
NaN
不应该与任何其他浮点值(包括
NaN
)相等。为了允许浮点值被排序或者在基于
树的索引中使用,
KingbaseES
将
NaN
值视为相等,并且比所有非
NaN
值要更大。
KingbaseES
还支持
SQL
标准表示法
float
和
float(p
)
用于声明非精确的数字类型。在这里,
“p“
指定以
二进制位表示的最低可接受精度。在选取
real
类型的时候,
KingbaseES
接受
float(1)
到
float(24)
,
在选取
double precision
的时候,接受
float(25)
到
float(53)
。在允许范围之外的
“p“
值将导致
一个错误。没有指定精度的
float
将被当作是
double precision
。
1.4
序数类型
Note:
这一节描述了
KingbaseES
特有的创建一个自增列的方法。另一种方法是使用
SQL
标准的标识列特性,
smallserial
、
serial
和
bigserial
类型不是真正的类型,它们只是为了创建唯一标识符列而存在的
方便符号(类似其它一些数据库中支持的
AUTO_INCREMENT
属性)。在目前的实现中,下面一个语句:
CREATE TABLE tablename (
colname SERIAL
);
等价于以下语句:
CREATE SEQUENCE tablename_colname_seq AS integer;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval(
'tablename_colname_seq'
)
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename
.
colname;
因此,我们就创建了一个整数列并且把它的缺省值安排为从一个序列发生器取值。应用了一个
NOT NULL
约束以确保空值不会被插入(在大多数情况下你可能还希望附加一个
UNIQUE
或者
PRIMARY KEY
约束避
免意外地插入重复的值,但这个不是自动发生的)。最后,该序列被标记为“属于”该列,这样当列或表被删
除时该序列也会被删除。
Note:
因为
smallserial
、
serial
和
bigserial
是用序列实现的,所以即使没有删除过行,在出现在
列中的序列值可能有“空洞”或者间隙。如果一个从序列中分配的值被用在一行中,即使该行最终没有被成
功地插入到表中,该值也被“用掉”了。例如,当插入事务回滚时就会发生这种情况。更多信息参见
序列操
作函数
中的
nextval()
。
要使用
serial
列插入序列的下一个数值到表中,请指定
serial
列应该被赋予其缺省值。我们可以通过
在
INSERT
语句中把该列排除在列列表之外来实现,也可以通过使用
DEFAULT
关键字来实现。
类型名
serial
和
serial4
是等效的:两个都创建
integer
列。类型名
bigserial
和
serial8
也
一样,只不过它们创建一个
bigint
列。如果你预计在表的生存期中使用的标识符数目超过
2
31
个,那么
你应该使用
bigserial
。类型名
smallserial
和
serial2
也以相同方式工作,只不过它们创建一个
smallint
列。
为一个
serial
列创建的序列在所属的列被删除的时候自动删除。你可以在不删除列的情况下删除序列,
但是这会强制删除该列的默认值表达式。