数字型包含4字节整数、4字节和8字节浮点数以及固定精度的小数。
在下面的表中列出了可以使用的数字型。
名称 | 存储空间 | 描述 | 范围 |
BINARY INTEGER | 4 bytes | 有符号整数,integer的别名。 | -2,147,483,648到+2,147,483,647 |
DOUBLE PRECISION | 8 bytes | 可变精度,不精确。 | 15位小数精度 |
INTEGER | 4 bytes | 整数的常规选择。 | -2,147,483,648到+2,147,483,647 |
NUMBER | Variable | 用户指定的精度,精确。 | 精度高达1000位 |
NUMBER(p [, s ] ) | Variable | 最大精度p和可选刻度s的精确数字。 | 精度高达1000位 |
PLS INTEGER | 4 bytes | 有符号整数,integer的别名。 | -2,147,483,648到+2,147,483,647 |
REAL | 4 bytes | 可变精度,不精确。 | 6位小数精度 |
ROWID | 8 bytes | 带符号的8位整数。 | -9223372036854775808到9223372036854775807 |
SMALLINT | 2 bytes | 小范围整数。 | -32768到+32767 |
BIGINT | 8 bytes | 大范围整数。 | -9223372036854775808到+9223372036854775807 |
DECIMAL | 可变长 | 用户指定的精度,精确。 | 小数点前131072位到小数点后16383位 |
NUMERIC | 可变长 | 用户指定的精度,精确。 | 小数点前131072位到小数点后16383位 |
SMALLSERIAL | 2 bytes | 2字节。 | 1到32767 |
SERIAL | 4 bytes | 自增整数。 | 1到2147483647 |
BIGSERIAL | 8 bytes | 自增的大范围整数。 | 1到9223372036854775807 |
在下面的章节中会详细介绍这些数据类型。
整数类型
类型INTEGER存储整个数值(不带有小数部分),数值区间为-2,147,483,648到+2,147,483,647。 如果尝试存储超出允许范围的数值,将会产生错误。
一般只有在磁盘空间紧张时才使用SMALLINT。 当INTEGER的取值范围不足时才使用BIGINT。
类型ROWID的列保存固定长度的二进制数据,这些数据描述了一个记录的实际地址。类型ROWID是一个无符号的、4字节的INTEGER,能够存储整个数值(不带有小数部分),数值区间为0 和 4,294,967,295。如果尝试存储超出允许范围的数值,将会产生错误。
带有任意精度的数值
NUMBER类型能够用于存储对于精度位数没有限制的数字,并且可以用于执行精确计算。当要求高精确度时,推荐使用这种类型来存储货币总量和其他类型的数量值。但是与下一章节中介绍的浮点类型相比,对于NUMBER类型数值的计算速度很慢。
下面是我们所使用的术语:NUMBER类型数值的范围是小数点右边部分的小数位数。NUMBER类型数值的精度是指整个数值包含的所有数字,也就是小数点左右两边的所有数字。所以,我们可以说数值23.5141的精度为6,范围是4。我们可以认为整数的范围是0。
NUMBER类型数值的精度和范围是可以配置的。通过使用下面所示的语法,可以把列的数据类型声明为NUMBER。
NUMBER(precision, scale)
精度必须为正数,范围可以是0或正数,我们也可以采用如下方法声明:
NUMBER(precision)
指定数值范围为0。而通过将列指定为不带任意精度和范围的NUMBER类型,可以列中存储任意精度和范围的数值,其中精度值可达到实际应用的上限。这种类型的列将不会把输入值强制为转换为任意特定的范围。如果列的数据类型是带有范围的NUMBER类型,那么会强制把输入值的范围转换为指定范围。(SQL标准中要求缺省的范围值为0,例如:强制指定数值的精度为整数的精度,从最方便使用的角度考虑,最好明确地指定精度和范围)。
如果数值的精度或者范围大于列的数据类型所声明的精度和范围,那么系统将会试图对这个值进行四舍五入。如果不能对数值进行四舍五入的处理来满足数据类型的限制,则会产生一个错误。
NUMERIC、DECIMAL两种数据类型和NUMBER是等效的。
浮点类型
数据类型REAL和 DOUBLE PRECISION属于非精确,可变精度的数值类型。实际上,这些类型通常是对于二进制浮点算术(分别是单精度和双精度)的IEEE标准754的具体实现,在一定范围内由特定的处理器,操作系统和编译器所支持。
非精确的含义是不能将一些数值精确地转换成内部格式,并且这些数值只能以近似值的形式存储。
所以在存储和打印出的这类数值时可能有一点差异。对这些错误进行管理以及这些错误如何在整个计算过程中传递是整个数学和计算机科学的分支需要研究的课题,除了以下几点,其余将不做更进一步的讨论。
如果要求精确存储和计算数值(例如货币总量),可以使用NUMBER类型。
如果您想用这些数据类型对重要的数据进行复杂计算,特别是当必须依靠在边界情况(无穷大,下溢)的特定行为时,应该仔细评估相关的实现方法。
比较两个浮点类型的值可能不会得到预想的结果。在大多数平台上,REAL类型数值的范围是1E-37到1E+37,精度至少是6个小数位。DOUBLE PRECISION的范围通常是1E-307 到1E+308,精度至少是15位。太大或者太小的值都会引发错误。如果输入数值的精度太高的话,就会发生四舍五入的操作。太小接近于零的数值无法与零区分开,将会产生一个下溢的错误。
PolarDB同样也支持标准 SQL语法的FLOAT和FLOAT(P), 这样可以指定非精确数值类型。在这里P指定在二进制数字中可接受的最小精度。PolarDB把从FLOAT(1)到FLOAT(24)的数据类型当作REAL类型,把从FLOAT(25)到FLOAT(53)的数据类型当作DOUBLE PRECISION类型。超出允许范围的P值会引发一个错误。没有指定精度的浮点数被当成DOUBLE PRECISION类型。
序列号类型
SMALLSERIAL、SERIAL和BIGSERIAL不是真正的数字类型,只是为在表中创建唯一标识做的概念上的便利。类似其它一些数据库中AUTO_INCREMENT属性,可以通过以下语句实现:
CREATE TABLE tablename (
colname SERIAL
);
等价于以下几条语句:
CREATE SEQUENCE tablename_colname_seq;
CREATE TABLE tablename (
colname integer NOT NULL DEFAULT nextval('tablename_colname_seq')
);
ALTER SEQUENCE tablename_colname_seq OWNED BY tablename.colname;
因此,我们便创建了一个整数字段并且将它的默认数值安排为从一个序列发生器读取。 应用了一个NOT NULL约束以确保NULL不会被插入。 在大多数情况下可以附加一个UNIQUE或PRIMARY KEY约束避免意外地插入重复的数值,但这个不是自动的。最后, 将序列发生器"从属于"那个字段,这样当该字段或表被删除时也一并删除它。
因为SMALLSERIAL、SERIAL和BIGSERIAL是使用序列实现的,所以列中的值,即使没有删过,也有可能出现不连续的情况。 即使从未成功将包含序列分配值的行插入表列,也仍会消耗从序列中分配的值。例如,如果插入事务回滚,可能会出现这种情况。
在SERIALl字段中插入序列中的下一个数值,需要给SERIAL字段赋予默认值。我们可以通过在INSERT语句中把该字段排除在字段列表之外来实现,也可以通过使用DEFAULT关键字来实现。
类型名SERIALl和SERIALl4是等效的: 两者都创建INTEGER字段。类型名BIGSERIAL和SERIALl8是等效的,只不过BIGSERIAL会创建一个BIGINT字段。 如果在表的生存期中使用的标识数目可能超过231个, 则应该使用BIGSERIAL。类型名SMALLSERIAL和SERIAL2是等效的,只不过SMALLSERIAL会创建一个SMALLINT字段。
一个SERIAL类型创建的序列在所属的字段被删除时会自动删除。 您可以只删除序列而不删除字段,不过这将删除该字段的默认值表达式。