DB2 9.7 提供了许多新的 SQL 功能:包括新的 SQL 数据操纵语句,以及 DECFLOAT(十进制浮点小数)、NUMBER、VARCHAR2 和 TIMPSTAMP 等新的数据类型在 IBM InfoSphere Federation Server 上的应用。本文主要是介绍一下 IBM InfoSphere Federation Server 对十进制浮点数(DECFLOAT)的支持。
DECFLOAT 简介
DECFLOAT 是 DB2 9.5 引入的一种新的数据类型,它是一种十进制浮点数据类型,适合处理精确的十进制业务数据。浮点数据类型例如 REAL 和 DOUBLE 类型都只是通过二进制近似方式来处理十进制数据,所以它们不适合大部分使用十进制数据的商业应用。
DECFLOAT 合并了 DECIMAL 类型的精度和 FLOAT 类型的一些性能优势,所以它是一种结果精确而且处理高效的数据类型。
DECFLOAT 提供 16 位和 34 位两种精度的浮点数据类型。分别为表示为 DECFLOAT(16) 和 DECFOAT(34)。如果没有指明精度,DECFLOAT 默认为 DECFLOAT(34)。这两种精度的数据分别存储在 8 字节和 16 字节的空间里。
表 1. DECFLOAT 类型数据表示范围
精度(位) | 长度(字节) | 范围 |
16 | 8 | -9.999999999999999 x 10384to -1.0 x 10-383: 1.0 x 10-383to 9.999999999999999 x 10384 |
34 | 16 | -9.999999999999999999999999999999999 x 106144to -1.0 x 10-6143: 1.0 x 10-6143to 9.999999999999999999999999999999999 x 106144 |
DECFLOAT 使用
下面通过一些例子,简单地描述以下 DECFLOAT 类型的基本用法。我们首先创建一个包含 DECFLOAT 类型的表,往表中插入一些数据。
CREATE TABLE EMPLOYEE
(
SALARY DECFLOAT,
BONUS DECFLOAT(16),
COMMISSION DECFLOAT(34)
);
INSERT INTO EMPLOYEE VALUES
(
1234567890123456789,
12345678901234,
1234567890123456789012345678901
);
SELECT * FROM EMPLOYEE;
SALARY | BONUS | COMMISSION |
1234567890123456789 | 12345678901234 | 1234567890123456789012345678901 |
在 DB2 9.5 之前,我们最多只能往数据库中插入由 DECIMAL 类型支持的 31 位长的浮点数据。然而,由于 DB2 9.5 引入了 DECFLOAT 数据类型,我们可以插入超过 31 位长的浮点数据。
DELETE FROM EMPLOYEE;
INSERT INTO EMPLOYEE VALUES
(
1234567890123456789,
DECFLOAT('1234567890123456789012345678902'),
DECFLOAT('1234567890123456789012345678901234')
);
SELECT * FROM EMPLOYEE;
SALARY | BONUS | COMMISSION |
1234567890123456789 | 1.234567890123457E+30 | 1234567890123456789012345678901234 |
注:由于 DECFLOAT(16) 类型没有足够的位来显示整个数据,BONUS 列的数据采用指数类型表示。
DECFLOAT(16) 占用 8 字节空间而 DECFLOAT(34) 占用 16 字节空间。DEC(31,0) 占用的空间必须在软件层面计算出来,而 DECFLOAT 在硬件层面就已经潜在地表示为 16 字节数据。
TBNAME | NAME | COLTYPE | LENGTH | SCALE |
EMPLOYEE | BONUS | DECFLOAT | 8 | 0 |
EMPLOYEE | COMMISSION | DECFLOAT | 16 | 0 |
EMPLOYEE | SALARY | DECFLOAT | 16 | 0 |
我们再通过下面这个例子来说明 DECFLOAT 类型和 DECIMAL 类型的不同。
DROP TABLE EMPLOYEE;
CREATE TABLE EMPLOYEE
(
SALARY DEC(14,2),
BONUS DECFLOAT(16),
COMMISSION DECFLOAT(34)
);
INSERT INTO EMPLOYEE VALUES
(
123456.78,
1234567890.12,
123456789012345678901234.56
);
SELECT * FROM EMPLOYEE;
SALARY | BONUS | COMMISSION |
123456.78 | 1234567890.12 | 123456789012345678901234.56 |
如果我们插入精度更大的数据,对于 BONUS 和 COMMISSION 这两列,我们不需要作任何更改,而对于 SALARY 列,那就需要修剪数据使得数据符合 DECIMAL 列指明的精度。
INSERT INTO EMPLOYEE VALUES
(
123456.7891,
1234567890.1234,
123456789012345678901234.5678
);
SELECT * FROM EMPLOYEE;
SALARY | BONUS | COMMISSION |
123456.78 | 1234567890.1234 | 123456789012345678901234.5678 |
DECFLOAT 舍入模式
DECFLOAT 数据类型允许使用不同形式的舍入模式(rounding)。舍入模式是指当数据值超过数据类型的精度时,应该如何舍入数据。DB2 通过 decflt_rounding 配置参数来控制舍入模式,这是在数据库级上实现的。一个应用程序是无法改变舍入模式的,但是可以通过 CURRENT DECFLOAT ROUNDING MODE 命令来查询当前的舍入模式。
DB2 支持五种符合 IEEE 标准的十进制浮点数舍入模式。舍入模式指定在计算结果超过精度时如何舍入结果。所有舍入模式的定义如下所示:
ROUND_CEILING
向正无穷大方向舍入。如果删除的所有位都是零,或者符号为负号,那么结果不变。 否则,结果系数应增加 1(向上舍入)。12.456 和 12.451 舍入后为 12.46。
ROUND_DOWN
朝着 0 的方向舍入(截断),忽略被废弃的位。12.456 和 12.451 舍入后为 12.45。
ROUND_FLOOR
向负无穷大方向舍入。如果删除的所有位都是零,或者符号为正号, 那么结果不变。否则,如果符号为负号,那么结果系数应增加 1。12.456 和 12.451 舍入后为 12.45。 和 ROUND_DOWN 不同的是,对于负数例如 -12.456,舍入后为 -12.46,而 ROUND_DOWN 模式舍入后为 -12.45。
ROUND_HALF_EVEN
舍入为最接近的整数。如果向上舍入与向下舍入是等距的,那么按照使得最后一位为偶数的目标来进行舍入;如果被废弃的位大于它左边位置中值 1 的一半(0.5),那么结果系数应增加 1(向上舍入);如果它们小于一半,那么不会调整结果系数,即忽略被废弃的位。否则,如果结果系数最右边的一位是偶数,在它们表示刚好一半的情况下,结果系数不会改变;如果结果系数最右边的一位是奇数,那么结果系数应增加 1(向上舍入),以使它变成偶数位。根据 IEEE 十进制浮点数规范,此舍入模式是缺省舍入模式,并且它是 DB2 产品中的缺省舍入模式。12.456 舍入后为 12.46。12.445 舍入后为 12.44。
ROUND_HALF_UP
舍入为最接近的整数。如果向上舍入与向下舍入是等距的,那么向上舍入并使结果系数增加 1;如果被删除的位大于或等于它左边位置中值 1 的一半(0.5),那么结果系数应增加 1(向上舍入)。否则,将忽略被删除的位(小于或等于 0.5)。12.456 舍入后为 12.46,12.451 舍入后为 12.45。
如果没有特别的设置指明,DB2 默认的舍入模式为 ROUND_HALF_EVEN。
表 2. DECFLOAT 类型数据在不同舍入模式下的结果
舍入模式 | 12.341 | 12.345 | 12.349 | 12.355 | -12.345 |
ROUND_CEILING | 12.35 | 12.35 | 12.35 | 12.36 | -12.34 |
ROUND_FLOOR | 12.34 | 12.34 | 12.34 | 12.35 | -12.35 |
ROUND_HALF_UP | 12.34 | 12.35 | 12.35 | 12.36 | -12.35 |
ROUND_HALF_EVEN | 12.34 | 12.34 | 12.35 | 12.36 | -12.34 |
ROUND_DOWN | 12.34 | 12.34 | 12.34 | 12.35 | -12.34 |
Federation DECFLOAT 支持
前面我们说过 DB2 v9.5 引入了 DECFLOAT 这种新的数据类型。而后 IBM InfoSphere Federation Server v9.7 也引入 DECFLOAT 数据类型,使得 DECFLOAT 可以支持联邦数据库环境。这就意味着,当远程数据库中有一个 DECFLOAT 数据,在联邦数据库环境下,本地数据库也有一个 DECFLOAT 数据与之相对应,可以实现远程的与本地的 DECFLOAT 类型的数据映射。因此,我们通过 IBM InfoSphere Federation Server 来透明地访问和控制远程 DECFLOAT 类型的数据。
IBM InfoSphere Federation Server v9.7 对于 DECFLOAT 的支持只适用于远程数据库为 DB2 LUW V9.5 及以上版本和 Oracle 的应用情况。
Federation DECFLOAT 使用
由于 IBM InfoSphere Federation Server 支持 DECFLOAT 数据类型,因此我们可以在包含 DECFLOAT 类型的远程对象(表或是视图)上创建昵称(NICKNAME)。例如,假设在远程创建下列 DB2/LUW 表:
创建一个包含 16 位 DECFLOAT 类型列的表:
CREATE TABLE T1 (c1 DEC