这是本节的多页打印视图。
点击此处打印.
返回本页常规视图.
数字数据类型
数字数据类型是存储在数据库列中的数字。这些数据类型通常按照下列方式分类:
不支持从 INTEGER
、FLOAT
和 NUMERIC
到 VARCHAR
的隐式转换。如果您需要该功能,可使用下列形式之一进行显式转换:
CAST(numeric-expression AS data-type)
numeric-expression::data-type
例如,您可以将浮点数转换为整数,如下所示:
=> SELECT(FLOAT '123.5')::INT;
?column?
----------
124
(1 row)
字符串到数字的数据类型转换针对科学记数法、二进制记数法、十六进制和数字型字面量组合,接受带引号常数的格式:
-
科学记数法:
=> SELECT FLOAT '1e10';
?column?
-------------
10000000000
(1 row)
-
BINARY
缩放:
=> SELECT NUMERIC '1p10';
?column?
----------
1024
(1 row)
-
十六进制:
=> SELECT NUMERIC '0x0abc';
?column?
----------
2748
(1 row)
1 - DOUBLE PRECISION (FLOAT)
Vertica 支持数字数据类型 DOUBLE PRECISION
,此为 IEEE-754 8 位浮点类型,适用于大多数常规浮点运算。
语法
[ DOUBLE PRECISION | FLOAT | FLOAT(n) | FLOAT8 | REAL ]
参数
注意
在浮点算法不遵循 IEEE-754 标准的计算机上,这些值的特性行为可能与预期不符。
双精度是一种非精确、精度可变的数字类型。换言之,某些值无法精确表示,而是存储为近似值。因此,涉及双精度的输入和输出操作可能会有些许偏差。
-
所有 DOUBLE PRECISION
数据类型都等同于 64 位 IEEE 浮点型。
-
FLOAT(n)
中的 n 必须介于 1 和 53 之间(包含),但始终使用 53 位小数。有关详细信息,请参阅 IEEE-754 标准。
-
要进行精确的数字存储和计算(例如对于金钱),请使用 NUMERIC
。
-
浮点计算受限于底层处理器、操作系统和编译器的行为。
-
比较两个浮点值是否相等,结果可能与预期不符。
-
虽然 Vertica 在内部将十进制值视为 FLOAT
,但如果将列定义为 FLOAT
,则您无法从 ORC 和 Parquet 文件中读取十进制值。在这些格式中,FLOAT
和 DECIMAL
是不同的类型。
值
接受以下格式的浮点数据:
十进制数
十进制数由一组非空十进制数字序列组成,可能包含基点字符(小数点 "."),其后可跟十进制指数(可选)。十进制指数表示乘以 10 的若干次幂,其构成为:字母 E 或 e,后跟加号或减号(可选),之后跟一组非空十进制数字序列。
十六进制数
十六进制数由 "0x" 或 "0X" 后跟一组非空十六进制数字序列构成,可能包含基点字符,其后可跟二进制指数(可选)。二进制指数表示乘以 2 的若干次幂,其构成为:字母 "P" 或 "p" ,后跟加号或减号(可选),之后跟一组非空十进制数字序列。基点字符和二进制指数这两者必须至少出现一个。
无穷大
无穷大为 INF
或 INFINITY
,表示忽略的情况。
NaN(非数值)
NaN 为 NAN
(忽略的情况),其后可跟括在括号内的字符序列(可选)。字符串以实现相关的方式指定 NaN 的值。(在 x86 机器上,NAN 在 Vertica 内部表示为 0xfff8000000000000LL。)
将无穷大或 NAN 值作为常数写入 SQL 语句时,需加单引号。例如:
=> UPDATE table SET x = 'Infinity'
注意
Vertica 遵照 IEEE 对 NaN 的定义 (IEEE 754)。SQL 标准不指定浮点的具体作用方式。
IEEE 将 NaN 定义为:一组浮点值,其中每个值均不与任何值相等,甚至不与其本身相等。NaN 不大于同时也不小于任何值(甚至是本身)。换句话说,每当涉及到 NaN,比较始终返回 false。
但是,为了对数据进行排序,NaN 值必须放在结果中的某个位置。在浮点数上下文中出现的生成的 'NaN' 值与硬件生成的 NaN 值相符。例如从技术角度看,由 Intel 硬件生成 (0xfff8000000000000LL) 的负的、静默的、非信令 NaN。
Vertica 使用不同的 NaN 值来表示浮点 NULL (0x7ffffffffffffffeLL)。这是一个正的、静默的、非信令 NaN,由 Vertica 预留。
后面提供了 NaN 的一个示例。
=> SELECT CBRT('Nan'); -- cube root
CBRT
------
NaN
(1 row)
=> SELECT 'Nan' > 1.0;
?column?
----------
f
(1 row)
Null 值
Null 值的加载文件格式是用户定义的,如 COPY
命令中所述。Null 值在 Vertica 内部表示为 0x7fffffffffffffffLL。交互格式由
vsql 打印选项 null 控制。例如:
\pset null '(null)'
默认选项为不打印任何内容。
规则
-
-0 == +0
-
1/0 = 无穷大
-
0/0 == Nan
-
NaN != 任意值(甚至 NaN)
要搜索 NaN 列值,请使用以下谓词:
... WHERE column != column
这是必要的,因为根据定义,WHERE
*column *= 'Nan'
不能为 true。
排序顺序(升序)
注意
2 - INTEGER
有符号的 8 字节 (64 位) 数据类型。
语法
[ INTEGER | INT | BIGINT | INT8 | SMALLINT | TINYINT ]
参数
INT
、INTEGER
、INT8
、SMALLINT
、TINYINT
以及 BIGINT
是针对同一种有符号 64 位整数数据类型的所有同义词。当不需要完整的 64 位时,可采用自动压缩技术来节省磁盘空间。
注意
-
值的范围为 –2^63+1 到 2^63-1。
-
2^63 = 9,223,372,036,854,775,808 (19 位数)。
-
–2^63 被保留,表示 NULL。
-
NULL
按升序最先显示(最小)。
-
Vertica 不具有显式 4 字节(32 位整数)或较小类型。Vertica 编码及自动压缩可以降低不足 64 位值的存储开销。
限制
-
JDBC 型 INTEGER 有 4 个字节,不受 Vertica 的支持。请改为使用 BIGINT
。
-
Vertica 不支持 SQL/JDBC 型 NUMERIC
、SMALLINT
或 TINYINT
。
-
Vertica 不检查溢出(正或负),聚合函数 SUM
()
除外。如果在使用 SUM
时遇到溢出问题,请使用 SUM_FLOAT
()
将其转换为浮点。
另请参阅
数据类型强制转换表
3 - NUMERIC
数字数据类型存储定点数字数据。例如,价值 $123.45 可存储于 NUMERIC(5,2)
字段。请注意,第一个数字(精度)指定总位数。
语法
numeric‑type [ ( precision[, scale] ) ]
参数
默认精度和标度
NUMERIC
、DECIMAL
、NUMBER
和 MONEY
的默认精度和标度值不同:
支持的编码
Vertica 支持 数字数据类型的以下编码:
有关详细信息,请参阅编码类型。
数字与整数和浮点数据类型
数字数据类型是存储具有特定精度和标度的值的精确数据类型,通过小数点前后的若干数字表示。这与 Vertica 整数和浮点数据类型形成对比:
NUMERIC 数据类型是非整数常量的首选,因为其结果总是精确的。例如:
=> SELECT 1.1 + 2.2 = 3.3;
?column?
----------
t
(1 row)
=> SELECT 1.1::float + 2.2::float = 3.3::float;
?column?
----------
f
(1 row)
数字操作
支持的数字操作如下:
-
NUMERIC 除数运算直接运行于数字值,不会转换为浮点数。运算结果具有至少 18 位,且四舍五入。
-
NUMERIC 模数运算(包括%)直接运行于数字值,不会转换为浮点数。结果与分子具有相同标度,无需四舍五入。
-
一些使用数字数据类型复杂操作会导致隐式转换为 FLOAT。使用 SQRT、STDDEV、超越函数,例如 LOG 以及 TO_CHAR/TO_NUMBER 格式化时,结果总是 FLOAT。
示例
下面的一系列命令创建一个包含数字数据类型的表,并对数据执行一些数学运算。
=> CREATE TABLE num1 (id INTEGER, amount NUMERIC(8,2));
向表中插入一些值:
=> INSERT INTO num1 VALUES (1, 123456.78);
查询表:
=> SELECT * FROM num1;
id | amount
------+-----------
1 | 123456.78
(1 row)
下面的例子从表 num1 返回 NUMERIC 列、总数:
=> SELECT amount FROM num1;
amount
-----------
123456.78
(1 row)
下面的语法在总数上加一 (1):
=> SELECT amount+1 AS 'amount' FROM num1;
amount
-----------
123457.78
(1 row)
下面的语法将总数列乘以 2:
=> SELECT amount*2 AS 'amount' FROM num1;
amount
-----------
246913.56
(1 row)
下面的语法为总数列返回负数:
=> SELECT -amount FROM num1;
?column?
------------
-123456.78
(1 row)
下面的语法返回总数实参的绝对值:
=> SELECT ABS(amount) FROM num1;
ABS
-----------
123456.78
(1 row)
下面的语法将 NUMERIC 总数转换为 FLOAT 数据类型:
=> SELECT amount::float FROM num1;
amount
-----------
123456.78
(1 row)
另请参阅
算数函数
4 - 数值数据类型溢出
Vertica 不检查溢出(正或负),聚合函数 SUM
()
除外。如果在使用 SUM
时遇到溢出问题,请使用 SUM_FLOAT
()
将其转换为浮点。
有关在将函数 SUM、SUM_FLOAT 和 AVG 用于数值数据类型时 Vertica 如何处理溢出的详细讨论,请参阅SUM、SUM_FLOAT 和 AVG 的数字数据类型溢出。讨论中包括关于关闭静默数值溢出和设置数值数据类型精度的指令。
除以零会返回错误:
=> SELECT 0/0;
ERROR 3117: Division by zero
=> SELECT 0.0/0;
ERROR 3117: Division by zero
=> SELECT 0 // 0;
ERROR 3117: Division by zero
=> SELECT 200.0/0;
ERROR 3117: Division by zero
=> SELECT 116.43 // 0;
ERROR 3117: Division by zero
将作为 FLOAT 的零除以零会返回 NaN:
=> SELECT 0.0::float/0;
?column?
----------
NaN
=> SELECT 0.0::float//0;
?column?
----------
NaN
将非零 FLOAT 除以零会返回 Infinity:
=> SELECT 2.0::float/0;
?column?
----------
Infinity
=> SELECT 200.0::float//0;
?column?
----------
Infinity
加法、减法和乘法运算忽略溢出。求和运算和求平均运算在内部使用 128 位算术。SUM
()
会在最终结果溢出时报错,并建议使用 SUM_FLOAT
(INT)
,将 128 位总和转换为 FLOAT
。例如:
=> CREATE TEMP TABLE t (i INT);
=> INSERT INTO t VALUES (1<<62);
=> INSERT INTO t VALUES (1<<62);
=> INSERT INTO t VALUES (1<<62);
=> INSERT INTO t VALUES (1<<62);
=> INSERT INTO t VALUES (1<<62);
=> SELECT SUM(i) FROM t;
ERROR: sum() overflowed
HINT: try sum_float() instead
=> SELECT SUM_FLOAT(i) FROM t;
SUM_FLOAT
---------------------
2.30584300921369e+19
5 - SUM、SUM_FLOAT 和 AVG 的数字数据类型溢出
使用具有 NUMERIC 数据类型的函数 SUM、SUM_FLOAT 和 AVG 时,请注意可能会发生溢出以及 Vertica 如何响应溢出。
此讨论适用于聚合函数和分析函数。
对于查询,当使用具有 NUMERIC 数据类型的函数 SUM、SUM_FLOAT 和 AVG 时,如果超出指定的精度,Vertica 允许静默溢出。
将 SUM 或 SUM_FLOAT 函数与 LAP 一起使用时,Vertica 也允许数字溢出。
默认溢出处理
对于 NUMERIC 数据类型,Vertica 在内部使用 18 位数的倍数。如果您指定的精度小于 18(例如,x(12,0)
),Vertica 允许溢出,最多包括 18 的第一个倍数。在某些情况下,如果对列 (SUM(x)
) 求和,则可能会超过 Vertica 内部为结果保留的位数。在这种情况下,Vertica 允许静默溢出。
关闭静默数字溢出
您可以关闭静默数字溢出,并指示 Vertica 隐式包含额外的数字位数。通过指定额外的空格,Vertica 可以一致地返回预期结果,即使超出 DDL 中指定的精度。
您可以通过将参数 AllowNumericOverflow 设置为 0 (false) 来关闭静默数字溢出。
当您将该参数设置为 0 时,Vertica 会考虑相应参数 NumericSumExtraPrecisionDigits 的值。
NumericSumExtraPrecisionDigits 参数默认为 6,这意味着 Vertica 在内部添加了超出 DDL 指定精度的六位。添加额外的精度位数可让 Vertica 一致地返回溢出 DDL 指定精度的结果。但是,在内部超出 18 的第二个倍数可能会对性能产生影响。
示例:
-
假设您的 DDL 指定 11(例如,x(11,0)
),并且您接受默认值 NumericSumExtraPrecisionDigits (6)。在这种情况下,Vertica 在内部保持在 18 位数的第一个倍数内,不会产生额外的性能影响。
-
在相同的示例中,如果将 NumericSumExtraPrecisionDigits 设置为 10,Vertica 会在内部超出阈值,进入 18 的第二个倍数。在性能方面,如果(假设)第一个示例是性能“a”,则第二个示例是“2a”,这大大增加了性能影响。超过 18 的第二个倍数后,性能影响仍然是“2a”。
此示例表示法显示,当您将 AllowNumericOverflow
设置为 0 (false) 时 Vertica 如何在内部做出响应。
如果您希望超过 DDL 中指定的精度,Vertica 建议您关闭静默数字溢出,并设置参数 NumericSumExtraPrecisionDigits。进入 18 的第二个倍数会影响性能。因此,在将 NumericSumExtraPrecisionDigits 设置为高于返回数字列的 SUM 所需的数字之前,请多加考虑。
请注意,如果您关闭 AllowNumericOverflow,并且超出由 NumericSumExtraPrecisionDigits 设置的额外精度位数,Vertica 将返回错误。
对实时聚合投影 (LAP) 的影响
对于 LAP,如果您的 LAP 使用 SUM 或 SUM_FLOAT 函数,Vertica 还允许静默数字溢出。要关闭 LAP 的静默数字溢出:
-
将参数 AllowNumericOverflow 设置为 0。
-
将参数 NumericSumExtraPrecisionDigits 设置为所需的隐式位数数值。或者,使用默认设置 6。
-
删除并重新创建您的 LAP。
如果您关闭静默数字溢出,请注意以下溢出导致回退或错误消息的情况。在这些示例中,AllowNumericOverflow 设置为 0 (false),每个 LAP 使用 SUM 或 SUM_FLOAT 函数。
当数字溢出关闭时:
-
负载可以在溢出时回退。
Vertica 在加载到 LAP 之前聚合数据。如果您正在插入、复制或合并数据,并且在 Vertica 正在聚合数据的加载期间发生溢出,则 Vertica 会回退加载。
-
加载后可能会发生溢出,因为 Vertica 会对现有数据求和。
Vertica 对现有数据总和的计算与其在数据加载期间执行的计算是分开的。如果您的 LAP 使用 SUM 或 SUM_FLOAT 选择列并且发生溢出,Vertica 会生成错误消息。此响应的方式类似于 Vertica 使用 SUM 或 SUM_FLOAT 函数为查询生成错误的方式。
-
在合并期间可能会发生溢出。
如果 Vertica 在 Tuple Mover 操作期间计算最终总和时发生溢出,Vertica 会在合并期间记录一条消息。如果发生错误,Vertica 会将 LAP 标记为过期。Vertica 不再使用过期的 LAP 运行 Tuple Mover 操作。