DatabaseMetaData.getColumns获取PostgreSQL int列大小异常问题
为什么PostgreSQL JDBC返回的int类型列大小是10而不是4?
这个问题的核心其实是你误解了JDBC元数据里COLUMN_SIZE字段的含义——它不是列的物理存储字节数,而是对应数据类型的数值精度/最大显示宽度/定义长度,PostgreSQL的JDBC驱动是严格按照JDBC规范来返回这个值的,咱们逐个拆解你的例子:
- id列(int类型):PostgreSQL的int确实是4字节物理存储,但JDBC返回的10是这个类型能表示的最大数字位数(int的取值范围是-2147483648到2147483647,最大的数有10位),这是数值类型的精度定义,不是存储大小。
- active列(boolean类型):返回1刚好和物理存储的1字节一致,但这只是巧合——这里的1是boolean类型的逻辑“大小”(只有两种状态),不是驱动特意返回的存储字节数。
- name列(varchar(2)):返回2是你定义的字符长度,符合预期,因为字符串类型的
COLUMN_SIZE就是定义的字符数。 - long_id列(bigint类型):返回19是因为bigint的最大值9223372036854775807是19位数,同样是数值精度,而它的物理存储是8字节。
- created列(timestamptz类型):返回35是该类型字符串表示的最大长度(比如带时区的完整时间字符串最长大概35个字符),而它的物理存储其实是8字节。
如果想获取真实的物理存储字节数怎么办?
别再依赖COLUMN_SIZE了,直接查询PostgreSQL的系统表information_schema.columns,结合PostgreSQL内置类型的存储规则来计算:
比如可以执行这样的SQL:
SELECT column_name, udt_name, CASE udt_name WHEN 'int4' THEN 4 -- int类型的存储字节数 WHEN 'bool' THEN 1 -- boolean的存储字节数 WHEN 'int8' THEN 8 -- bigint的存储字节数 WHEN 'timestamptz' THEN 8 -- timestamptz的存储字节数 WHEN 'varchar' THEN character_maximum_length * 3 -- UTF8编码下每个字符最多3字节,可按需调整 END AS storage_bytes FROM information_schema.columns WHERE table_schema = 'public' AND table_name = 'test';
然后在Java代码里执行这个查询,就能拿到真实的存储大小了。
内容的提问来源于stack exchange,提问作者Almas Abdrazak
相关产品推荐
相关产品推荐

