如何仅基于PostgreSQL的atttypmod计算numeric精度、标度及字符长度
PostgreSQL atttypmod 字段值推导规则
字符类型字段长度计算
你观测到的atttypmod == 字段定义长度 +4规律完全成立,适用所有显式指定长度的字符类型(char(n)、varchar(n)):
- 直接用
atttypmod - 4即可得到字段定义的长度值,差值4是系统存储变长字段头预留的固定偏移,无业务含义。 - 特殊值说明:如果atttypmod为-1,对应无长度上限的
text类型、或未指定长度的varchar类型,不需要做长度计算。
numeric类型精度、标度计算
numeric类型的atttypmod采用高低位拆分存储的结构,固定计算规则如下,不需要依赖系统表即可推导:
- 存储结构说明:atttypmod为4字节整型,高16位存储numeric定义的精度(precision),低16位存储「标度(scale)+ 4」的结果,其中4同样是变长字段头预留偏移。
- 具体计算公式:
- 精度(precision)=
atttypmod >> 16(即atttypmod除以65536取整数商) - 标度(scale)=
(atttypmod & 0xFFFF) - 4(即atttypmod对65536取余后减4)
- 精度(precision)=
- 对应你提供的样例验证结果:
| 定义精度 | 定义标度 | atttypmod值 | 计算验证 |
|---|---|---|---|
| 5 | 2 | 327686 | 327686 >>16 = 5;327686 & 0xFFFF =6,6-4=2,完全匹配 |
| 5 | 1 | 327685 | 327685 >>16 =5;327685 &0xFFFF=5,5-4=1,完全匹配 |
| 6 | 3 | 393223 | 393223 >>16=6;393223&0xFFFF=7,7-4=3,完全匹配 |
| 4 | 4 | 262152 | 262152>>16=4;262152&0xFFFF=8,8-4=4,完全匹配 |
补充说明:如果atttypmod值为-1,对应无精度、标度约束的通用numeric类型,不需要做计算。以上规则适配PostgreSQL 8.4及以上所有正式版本,WAL日志中记录的atttypmod值与系统表存储值完全一致,可直接套用公式计算。
内容的提问来源于stack exchange,提问作者user3289736
相关产品推荐
相关产品推荐

