PostgreSQL表用户列最大个数

PostgreSQL表用户列最大个数

有些业务可能有这么个需求:需要增加用户列,即通过ALTER TABLE ... ADD...来添加用户列。那么PG/GP中是否会有列个数的限制呢?

它有1600列数的限制,并且没有方法去除掉这个限制。参见:

  https://github.com/greenplum-db/gpdb/issues/15409

1)接着,我们创建一个1600列的表,进行下验证:

CREATE TABLE t1(id1 int,id2 int,id3 int,...,id1600 int);

2)然后,添加一列:

test=# alter table t1 add column co1601 int;
psql: ERROR: table can have at most 1600 columns

会报错提示,表最大有1600列。此时如果再添加新列怎么办?能否添加呢?

3)我们drop一列,然后再添加一列,是否可以?

test=# alter table t1 drop column co1600;
ALTER TABLE
test=# alter table t1 add column co1600 int;
psql: ERROR: table can have at most 1600 columns

显然,并不能通过这种方式添加新列。

4)在我们认知中,删除掉一列,不是就空出一个名额了么,咋还不给添加新列?

GP issues中对此进行了讨论:

  https://github.com/greenplum-db/gpdb/issues/15459

显然,官方也没有计划对此行为进行修复。

Dropped columns are not removed from catalog. That's the behavior we inherit from upstream and avoids rewrite of table during drop column. So, no plans for now to modify the behavior. Understand it can be annoying. We are considering enhancing the behavior for Columnar tables to such reuse of dropped column for newly added columns. For now, closing the issue.

5)那么我们能否在代码中去掉这个限制,是否对其他地方有影响呢?

先看下,在什么地方限制的:

添加列的函数ATExecAddColumn,该函数对此进行限制的地方:

3270919fa74ba419aecaa6dbf00930ad.png

也就是宏MaxHeapAttributeNumber定义:#define MaxHeapAttributeNumber 1600

从上图可以看到限制的值来自pg_class系统表的relnatts字段。新增字段时,会对该字段进行更新:仍旧是ATExecAddColumn函数中:

fc0e679a2b4eaf9dd256b89c793ec383.png

Drop表时会对该字段进行更新吗?接着检查函数ATExecDropColumn,该函数将列删除后,并没有更新pg_class系统表的relnatts字段。OK,知道为什么删除一列,仍旧不能添加新列了吧。

6)如果,我们在ATExecDropColumn的地方将pg_class系统表进行更新,将该限制规避掉,是否可行?

需要知道,drop一列后,存于磁盘上表内的记录仍旧是完整列,也就是包含删除的列。在扫描时会将所有列值都扫描出来,投影时将删除的列去掉。修改后的后果:实际列超出1600,此时会对其他流程带来异常吗?

随便找下MaxHeapAttributeNumber使用的地方,比如toast_insert_or_update函数:

5e8eeaf08cd25c62dfc30562a5da8240.png

可以看到,有2个问题。如果修改这个限制的化,不是那么简单在drop列后更新pg_class系统表的relnatts字段值就可以的,需要仔细梳理代码,对其他流程受影响的地方都进行改造。当然,能否改造也需要打个问号,方便起见,还是对业务进行优化吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yzs87

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值