#数值型
数值型数据包括正负整数、小数、0、正负无穷(Inf、-Inf)、以及非数(Nan),主要应用于数学运算、数字计量等场景。YashanDB支持对此类数据的加减乘除取模运算,并提供统计函数和聚集函数来满足各式场景的需求。
可以将数值型数据进一步划分为整数类型(Integer Data Type)、浮点类型(Floating-Point Data Type)、NUMBER类型(Number Data Type)、以及BIT类型(Bit Data Type)。YashanDB为不同的数值类型定义了值域、字节长度、精度等属性。
# 整数类型(Integer Data Type)
整数类型为定长、精确数值类型,是没有小数部分的整数,具体包括TINYINT、SMALLINT、INT、BIGINT四种数据类型,每个类型有不同的字节长度和值域,建表时需要根据数据存储所需的空间来决定使用哪一种类型。
INTEGER、PLS_INTEGER/PLS_INTEGER为INTEGER的别名,行为完全同INT。
整数类型通过十进制精度(Decimal Precision,数字0~9)存储,在值域和精度范围以内的十进制数字都可以被准确的存储。
INT类型在语法上支持定义时带精度信息,精度范围为 0 ~ 255。
当配置参数USE_NATIVE_TYPE为FALSE时,TINYINT、SMALLINT、INT、BIGINT返回值类型为NUMBER,precision为38,scale为0。
示例
CREATE TABLE int_test(c1 INT(255));
INSERT INTO int_test VALUES(128);
SELECT c1 res FROM int_test;
RES
------------
128
# 存储属性
类型 | 字节长度 | 值域 |
---|---|---|
TINYINT | 1 | [-27 , 27 - 1] |
SMALLINT | 2 | [-215, 215 - 1] |
INT | 4 | [-231, 231 - 1] |
BIGINT | 8 | [-263, 263 - 1] |
# 浮点类型(Floating-Point Data Type)
浮点类型为定长、非精确数值类型,具体包括FLOAT、DOUBLE两种数据类型。在YashanDB中,浮点类型的行为与行业标准IEEE Standard 754保持一致。
BINARY_FLOAT、REAL为FLOAT的别名,行为完全同FLOAT。BINARY_DOUBLE为DOUBLE的别名,行为完全同DOUBLE。
浮点类型通过二进制精度(Binary Precision,数字0和1)存储。
- 浮点类型拥有更宽广的值域,可以表达特殊值Inf、-Inf、Nan,对小数点的位置也没有限制。
- 无法避免由于二进制精度转换至十进制精度所带来的误差,所以一些数字无法被浮点数类型准确的表达(例如0.1)。且精度根据USE_NATIVE_TYPE配置参数的值存在不同规则:
- 当USE_NATIVE_TYPE为TRUE时,YashanDB只做语法兼容,等价于浮点类型本身(例如DOUBLE
(p)
等价于DOUBLE)。 - 当USE_NATIVE_TYPE为FALSE时,FLOAT类型不适用于列存表,在行存表中,FLOAT类型不带精度信息时,默认为FLOAT(126),FLOAT后面带精度信息时,精度值为设置值。
- 当USE_NATIVE_TYPE为TRUE时,YashanDB只做语法兼容,等价于浮点类型本身(例如DOUBLE
# 存储属性
类型 | 字节长度 | 值域 | 可保证准确的十进制精度 |
---|---|---|---|
FLOAT | 4 | [-3.402823E38, -1.401298E-45] 0 [1.401298E-45, 3.402823E38] 数字3.402823和1.401298为四舍五入的值,非最精确值 | 6位 |
DOUBLE | 8 | [-1.79769313486232E308, -4.94065645841247E-324] 0 [4.94065645841247E-324, 1.79769313486232E308] 数字1.797693134862315807和4.94065645841247为四舍五入的值,非最精确值 | 15位 |
# 使用规则
# 定义格式
浮点类型有如下几种定义格式:
FLOAT
DOUBLE
FLOAT(m,d)
DOUBLE(m,d)
FLOAT(p)
DOUBLE(p)
其中,在USE_NATIVE_TYPE为TRUE时,(m,d)
和(p)
均为语法兼容格式,即支持DOUBLE(m,d)
和DOUBLE(p)
语法,但二者均等价于DOUBLE,无实际含义,但存在如下约束规则:
- m:Magnitude,0 < m <= 255
- d:Division, 0 <= d <= 30
- d <= m
- p:Precision,0 <= p <= 53
- 定义FLOAT类型时,0 <= p <= 126 ,大于53小于等于126的部分会当作53处理,如m或者p值超过23,系统将类型转换为DOUBLE类型
示例
--定义m超过23的FLOAT类型
DROP TABLE IF EXISTS float_tb;
CREATE TABLE float_tb(c FLOAT(24,1));
--系统将其转换为DOUBLE类型
DESC float_tb
NAME NULL? DATATYPE
----------------- --------- ---------------
C DOUBLE
其中,在USE_NATIVE_TYPE为FALSE时,在实现上支持FLOAT缺省或者带精度信息,存在如下规则:
- 当不带精度信息时, p = 126
- 当带精度信息时,1 <= p <= 126
示例(HEAP表)
DROP TABLE IF EXISTS float_tb;
CREATE TABLE float_tb(c FLOAT(2));
DESC float_tb
NAME NULL? DATATYPE
----------------- --------- ---------------
C FLOAT(2)
# 显示方式
浮点类型以科学计数法的形式显示。
# 特殊值
浮点类型有3个特殊值:Nan、Inf、-Inf。它们的大小排序为:Nan>Inf>正数>0>负数>-Inf。
下表列示一些特殊场景下将产生这些特殊值或0:
特殊场景 | 产生值 |
---|---|
大于浮点类型值域的最大值,但被用浮点数表示 | Inf |
小于浮点类型值域的最小值,但被用浮点数表示 | -Inf |
绝对值小于值域的最小绝对值,但被用浮点数表示 | 0 |
正浮点数或Inf作为被除数与0作除法 | Inf |
负浮点数或-Inf作为被除数,与0作除法 | -Inf |
Inf、-Inf之间作除法 | Nan |
Nan作为被除数,与0作除法 | Nan |
当浮点数大小超过值域的最大绝对值时,会被表示为Inf或-Inf;当浮点数大小小于值域的最小绝对值时,会被表示成0。
# 精度约束
当浮点类型的实际精度超过其最大精度限制时,超过精度的部分会被舍弃,且舍弃规则无法确定为四舍五入或截断,舍弃后数字的最大精度位的结果也无法预测。
由于存储方式的差异,将其他数值型转换为浮点类型时可能产生无法避免的误差。
因此,浮点类型不适合用在对精确程度要求较高的场景,也不适合用在涉及大量等于比较条件和边界值的场景。
示例
SET NUMWIDTH 30;
-- Example 1: 向FLOAT插入超过最大精度数字,超过最大精度位的部分被舍弃,且舍弃方式并非四舍五入或截断
CREATE TABLE number_f (c1 FLOAT);
INSERT INTO number_f VALUES (10.567895678956789);
COMMIT;
SELECT c1 FROM number_f;
C1
-------------------------------
1.05678959E+001
-- Example 2: 将NUMBER、整数类型转换为浮点类型会产生误差
CREATE TABLE number_bn (c1 BIGINT, c2 NUMBER(38, 60));
INSERT INTO number_bn VALUES (9223372036854775800, 0.000000000000000000000000000000000000000000000401298);
COMMIT;
SELECT c1,c2 FROM number_bn;
C1 C2
--------------------- -------------------------------
9223372036854775800 4.012980000000000000000000E-46
SELECT CAST(C1 AS FLOAT) float1,
CAST(C2 AS FLOAT) float2
FROM number_bn;
FLOAT1 FLOAT2
------------------------------- -------------------------------
9.22337204E+018 0
# NUMBER类型(Number Data Type)
NUMBER类型为非定长、精确的数值类型,它可以自由指定精度(P,Precision)和刻度(S,Scale)。NUMBER类型可以准确表示符合精度和刻度要求的任何数字,因此非常适合用于需要精确计算且涉及小数的场景。
DECIMAL、NUMERIC为NUMBER的别名,行为完全同NUMBER。
# 存储属性
类型 | 字节长度 | 值域 | 存储方式 |
---|---|---|---|
NUMBER | 1~22 | 0 绝对值 [1E-130,1E126) | 通过十进制精度(Decimal Precision,数字0~9)存储,在值域和精度范围以内的十进制数字都可以被准确的存储。 |
# 使用规则
# 定义格式
NUMBER类型的定义格式为NUMBER(P,S)
或NUMBER
,其中P和S的含义如下:
- P:精度,表示数字的有效位数(不包含小数点、正负符号的位数),取值范围[1,38];也可以为*,表示精度为38。
- S:刻度,表示数字从小数点到最右侧有效数字的位数,取值范围[-84,127]。刻度为正数,表示小数点在最小位数左侧(例如3.14的格式定义可以为
NUMBER(3, 2)
);刻度为负数,表示小数点在最小位数右侧(例如31400的格式定义可以为NUMBER(3, -2)
)。 - P-S:表示整数的最大位数。
当定义格式为NUMBER,不指定P/S时,表示为浮动精度。
# 精度约束
不指定P/S时为浮动精度,以实际计算产生的值为准,无精度限制。
指定P/S:
- 实际刻度超过定义的S时,系统将超过的部分四舍五入至最小刻度位。
- 实际精度超过定义的P时,系统报错。
# 支持科学记数法作为值输入
- 支持诸如1.24E3的格式处理。
- 异常带E的数值格式如E1,1E,1.3E2A等进行相应报错。
示例
-- Example 1: 将31401表示为number(3, -2)。因为最小刻度是百分位,31401会被四舍五入为31400
SELECT CAST(31401 AS NUMBER(3,-2)) FROM DUAL;
CAST(31401ASNUMBER(3
---------------------------------------------------
31400
-- Example 2: 将31400表示为NUMBER(1, -2)。因为最大精度是1,但31400有三位有效数字,所以会有larger than specified precision allowed报错
SELECT CAST(31400 AS NUMBER(1, -2)) FROM DUAL;
[1:34]YAS-00025 value is larger than specified precision allowed for this column
-- Example 3: 支持科学记数法作为值输入,同输入全数值有一致的结果
SELECT CAST('1.24E3' AS NUMBER) FROM DUAL;
CAST('1.24E3'ASNUMBE
---------------------------------------------------
1240
-- Example 4: 支持精度以*进行输入,精度为*时表示是38
SELECT CAST('12.38' AS NUMBER(*,0)) FROM DUAL;
CAST('12.38'ASNUMBER
--------------------
12
CREATE TABLE Etest7293 (NUM1 NUMBER(*,0),NUM2 NUMBER(*), NUM3 NUMBER, NUM4 NUMBER(*,23));
desc Etest7293;
NAME NULL? DATATYPE
--------------- --------- ---------------------
NUM1 NUMBER(38)
NUM2 NUMBER
NUM3 NUMBER
NUM4 NUMBER(38,23)
# BIT类型(Bit Data Type)
BIT类型支持1-64位宽度(Size)的二进制位图,每BIT位只允许存放0/1值,其他值将视为非法BIT类型。
以字符串形式插入/更新BIT类型时,字母b开头的字符串以二进制数值处理,其它以十进制字符串处理。
BIT类型以二进制输出。
BIT类型的定义格式为BIT[(Size)]
,Size:表示BIT的宽度,取值范围为[1,64]
,省略时,系统取默认值1。
BIT类型仅适用于HEAP表。
示例(HEAP表)
CREATE TABLE number_nb (numbera NUMBER,numberb BIT(64));
INSERT INTO number_nb VALUES (10,10);
SELECT numbera,numberb FROM number_nb;
NUMBERA NUMBERB
----------- ----------------------------------------------------------------
10 1010
# 显示宽度调整
SET NUMWIDTH用于设置浮点类型及NUMBER类型数据输出时的显示宽度,只针对当前会话有效。
其中,SET NUMWIDTH=SET NUM,用于设置显示宽度;SHOW NUMWIDTH=SHOW NUM,用于显示设置的宽度值。
系统对浮点类型及NUMBER类型数据输出时的显示宽度默认为10。
YashanDB对浮点类型数字均采用科学计数法显示,显示格式为:
- 正数 x.yyyyE{+|-}zzz
- 负数 -x.yyyyE{+|-}zzz
其中只有yyyy显示内容长度受到width限制;指数zzz固定显示3个字节,其前面固定显示符号'+' 或 '-'。
YashanDB对NUMBER类型数字的显示规则如下:
- 如果是纯小数,则小数点前的0会省略不显示。如果纯小数为0.00000xxx 其中xxx为任意数字,则使用科学计数法显示,否则使用非科学计数法显示。
- 如果是非纯小数,且给定的宽度能够完整输出整数内容,则不会使用科学计数法显示,否则使用科学计数法显示。
- NUMBER类型数字的科学计数法显示格式为:
- 正数: x.yyyyE{+|-}zz
- 负数:-x.yyyyE{+|-}zz
其中yyyy显示内容长度受到width限制;指数zz默认2个字节,最大3个字节,其前面固定显示符号'+' 或 '-'。
# 语句定义
set numwidth::=
show numwidth::=
width
该语句用于指定显示宽度值,值范围为[2,128]
。
当此值设置过小,导致某个数字无法完整显示出来时,系统输出按此值个数的'#'。
示例
--创建numbers_nfd表,包含NUMBER、FLOAT、DOUBLE三个类型的字段
CREATE TABLE numbers_nfd (cnumber NUMBER, fnumber FLOAT, dnumber DOUBLE);
INSERT INTO numbers_nfd VALUES (0.0000002334, 0.0000002334, -0.0000002334);
INSERT INTO numbers_nfd VALUES (2334.0000002334, 2334.0000002334, -2334.0000002334);
INSERT INTO numbers_nfd VALUES (233423342334.0000002334, 233423342334.0000002334, -233423342334.0000002334);
COMMIT;
-- 默认宽度下显示
SELECT cnumber,fnumber,dnumber FROM numbers_nfd;
CNUMBER FNUMBER DNUMBER
----------- ----------- -----------
2.3340E-07 2.334E-007 -2.33E-007
2334 2.334E+003 -2.33E+003
2.3342E+11 2.334E+011 -2.33E+011
-- 设置显示宽度为20
SET NUMWIDTH 20;
SELECT cnumber,fnumber,dnumber FROM numbers_nfd;
CNUMBER FNUMBER DNUMBER
--------------------- --------------------- ---------------------
.0000002334 2.33400002E-007 -2.334E-007
2334.0000002334 2.334E+003 -2.334000000233E+003
233423342334.0000002 2.3342334E+011 -2.33423342334E+011
-- 设置显示宽度为8
SET NUMWIDTH 8;
SELECT cnumber,fnumber,dnumber FROM numbers_nfd;
CNUMBER FNUMBER DNUMBER
--------- --------- ---------
2.33E-07 2.3E-007 ########
2334 2.3E+003 ########
2.33E+11 2.3E+011 ########
-- 设置显示宽度为5
SET NUMWIDTH 5;
SELECT cnumber,fnumber,dnumber FROM numbers_nfd;
CNUMBER FNUMBER DNUMBER
------- ------- -------
0 ##### #####
2334 ##### #####
##### ##### #####