一、语法与定义
DECIMAL[(precision[, scale])]
·Precision(精度):表示该数值的总位数(不含小数点)。
·范围:1 到 38。
·默认值:9。
·Scale(标度):表示小数点后的位数。
·必须小于或等于精度。
·默认值:0。
·默认状态:省略参数时,默认为 DECIMAL(9, 0)。
二、范围与极值
·取值范围: -10^38+1 到 10^38−1。
·最大值:由 DECIMAL(38, 0) 表示。
·最精密小数值:由 DECIMAL(38, 38) 表示(小数点后 38 位)。其最接近 0 的值为 0.000…1(37 个零),最接近 1 的值为 0.999…(38 个九)。
三、内存占用
DECIMAL 的内存占用仅由精度(Precision)决定,与标度无关。
| 精度 (Precision) | 内存占用 (In-memory Storage) |
| 1 – 9 | 4 字节 |
| 10 – 18 | 8 字节 |
| 19 – 38 | 16 字节 |
四、算术运算规则
TCHouse-X 的 DECIMAL 运算遵循严格的精度推导公式,最大精度为 38。若推导出的精度超过 38,TCHouse-X 将优先保留至少 6 位小数并进行四舍五入。
| 运算 | 结果精度 (Resulting Precision) | 结果标度 (Resulting Scale) |
| 加法 / 减法 | max(L1, L2) + max(S1, S2) + 1 | max(S1, S2) |
| 乘法 | P1 + P2 + 1 | S1 + S2 |
| 除法 | L1 + S2 + max(S1 + P2 + 1, 6) | max(S1 + P2 + 1, 6) |
| 取模 | min(L1, L2) + max(S1, S2) | max(S1, S2) |
注意:说明:
注意:变量定义:
五、隐式转换
·DECIMAL → DOUBLE/FLOAT:必要时会自动转换,但会丢失精度(故不推荐大量使用浮点型)。
·DOUBLE/FLOAT → DECIMAL:禁止隐式转换,必须显式使用 CAST()。
·整数 → DECIMAL:仅当目标 DECIMAL 有足够空间容纳该整数类型的最大位数时才允许。
·BIGINT 需要左侧保留 19 位;INT 10 位;SMALLINT 5 位;TINYINT 3 位。
六、显式转换
·CAST(STRING AS DECIMAL):
·如果字符串小数位多于目标标度,将执行四舍五入。
·支持科学计数法,如 CAST('1.0e6' AS DECIMAL(32, 0))。
·CAST(DECIMAL AS TIMESTAMP):返回 Unix 纪元(1970-01-01)之后 N 秒的时间点。在查询展示时,该值会自动转换为当前系统时区对应的本地时间。
七、与 FLOAT/DOUBLE 的对比
| 特性 | DECIMAL | FLOAT / DOUBLE |
| 精确性 | 绝对精确(适合金融计算) | 不精确,存在舍入误差 |
| 性能 | 运算开销略高 | 高性能(硬件指令加速) |
| 聚合一致性 | 结果可重复且稳定 | 大数据量 SUM/AVG 可能产生微小波动 |
| 分区 | 推荐,目录名与数值严格匹配 | 不推荐,目录名可能不符合预期 |
八、分区
使用 DECIMAL 列作为分区键比浮点数更可靠,因为其目录名称与数值完全对应,不会出现浮点数表示不精确导致的目录名误差。