这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

数字数据类型

数字数据类型是存储在数据库列中的数字。这些数据类型通常按照下列方式分类:

  • 精确 数字类型,需要保存值的精度和标度。精确数字类型有 INTEGERBIGINTDECIMALNUMERICNUMBERMONEY

  • 近似 数字类型,需要保存值的精度,标度可浮动。近似数字类型有 DOUBLE PRECISIONFLOATREAL

不支持从 INTEGERFLOATNUMERICVARCHAR 的隐式转换。如果您需要该功能,可使用下列形式之一进行显式转换:

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 ]

参数

双精度是一种非精确、精度可变的数字类型。换言之,某些值无法精确表示,而是存储为近似值。因此,涉及双精度的输入和输出操作可能会有些许偏差。

  • 所有 DOUBLE PRECISION 数据类型都等同于 64 位 IEEE 浮点型。

  • FLOAT(n) 中的 n 必须介于 1 和 53 之间(包含),但始终使用 53 位小数。有关详细信息,请参阅 IEEE-754 标准。

  • 要进行精确的数字存储和计算(例如对于金钱),请使用 NUMERIC

  • 浮点计算受限于底层处理器、操作系统和编译器的行为。

  • 比较两个浮点值是否相等,结果可能与预期不符。

  • 虽然 Vertica 在内部将十进制值视为 FLOAT,但如果将列定义为 FLOAT,则您无法从 ORC 和 Parquet 文件中读取十进制值。在这些格式中,FLOATDECIMAL 是不同的类型。

接受以下格式的浮点数据:

  • 前置空格(可选)

  • 加号 ("+") 或减号 ("-")(可选)

  • 十进制数、十六进制数、无穷大、NAN 或 NULL 值。

十进制数

十进制数由一组非空十进制数字序列组成,可能包含基点字符(小数点 "."),其后可跟十进制指数(可选)。十进制指数表示乘以 10 的若干次幂,其构成为:字母 E 或 e,后跟加号或减号(可选),之后跟一组非空十进制数字序列。

十六进制数

十六进制数由 "0x" 或 "0X" 后跟一组非空十六进制数字序列构成,可能包含基点字符,其后可跟二进制指数(可选)。二进制指数表示乘以 2 的若干次幂,其构成为:字母 "P" 或 "p" ,后跟加号或减号(可选),之后跟一组非空十进制数字序列。基点字符和二进制指数这两者必须至少出现一个。

无穷大

无穷大为 INFINFINITY,表示忽略的情况。

NaN(非数值)

NaN 为 NAN(忽略的情况),其后可跟括在括号内的字符序列(可选)。字符串以实现相关的方式指定 NaN 的值。(在 x86 机器上,NAN 在 Vertica 内部表示为 0xfff8000000000000LL。)

将无穷大或 NAN 值作为常数写入 SQL 语句时,需加单引号。例如:

=> UPDATE table SET x = 'Infinity'

后面提供了 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。

排序顺序(升序)

  • NAN

  • -Inf

  • 数字

  • +Inf

  • NULL

注意

  • NULL 按照升序在最后显示(最大值)。

  • 按照 IEEE 浮点标准,浮点数中的所有溢出均会生成 +/- 无穷大或 NaN。

2 - INTEGER

有符号的 8 字节 (64 位) 数据类型。

语法

[ INTEGER | INT | BIGINT | INT8 | SMALLINT | TINYINT ]

参数

INTINTEGERINT8SMALLINTTINYINT 以及 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 型 NUMERICSMALLINTTINYINT

  • Vertica 不检查溢出(正或负),聚合函数 SUM() 除外。如果在使用 SUM 时遇到溢出问题,请使用 SUM_FLOAT() 将其转换为浮点。

另请参阅

数据类型强制转换表

3 - NUMERIC

数字数据类型存储定点数字数据。例如,价值 $123.45 可存储于 NUMERIC(5,2) 字段。请注意,第一个数字(精度)指定位数。

语法

numeric‑type [ ( precision[, scale] ) ]

参数

默认精度和标度

NUMERICDECIMALNUMBERMONEY 的默认精度和标度值不同:

支持的编码

Vertica 支持 数字数据类型的以下编码:

  • 精度 ≤ 18:AUTOBLOCK_DICTBLOCKDICT_COMPCOMMONDELTA_COMPDELTAVALGCDDELTARLE

  • 精密 >18:AUTOBLOCK_DICTBLOCKDICT_COMPRLE

有关详细信息,请参阅编码类型

数字与整数和浮点数据类型

数字数据类型是存储具有特定精度和标度的值的精确数据类型,通过小数点前后的若干数字表示。这与 Vertica 整数和浮点数据类型形成对比:

  • DOUBLE PRECISION (FLOAT) 支持 ~15 数字、变指数,近似表示数字值。它可能不如 NUMERIC 数据类型精确。

  • INTEGER 支持 ~18 数字,仅限整数。

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 的静默数字溢出:

  1. 将参数 AllowNumericOverflow 设置为 0。

  2. 将参数 NumericSumExtraPrecisionDigits 设置为所需的隐式位数数值。或者,使用默认设置 6。

  3. 删除并重新创建您的 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 操作。