postgresql 修改字段长度的操作

使用数据库postgresql的时候,有时会遇到字段长度扩展的情况,由于之前已经有数据了,所以只能修改字段长度,不能通过删除再增加的方式。

可以使用如下方式进行

alter table your_table_name alter column your_column_name type character varying(3000);

通过上面的一句话就可以把你的表中相应的字段的长度修改为3000.

补充:postgresql字符类型长度变更的性能

背景

业务有时会遇到表中的字符型字段的长度不够用的问题,需要修改表定义。但是表里的数据已经很多了,修改字段长度会不会造成应用堵塞呢?

测试验证

做了个小测试,如下

建表并插入1000w数据

postgres=# create table tbx1(id int,c1 char(10),c2 varchar(10));
create table
postgres=# insert into tbx1 select id ,'aaaaa','aaaaa' from generate_series(1,10000000) id;
insert 0 10000000 

变更varchar类型长度

postgres=# alter table tbx1 alter column c2 type varchar(100);
alter table
time: 1.873 ms
postgres=# alter table tbx1 alter column c2 type varchar(99);
alter table
time: 12815.678 ms
postgres=# alter table tbx1 alter column c2 type varchar(4);
error: value too long for type character varying(4)
time: 5.328 ms 

变更char类型长度

postgres=# alter table tbx1 alter column c1 type char(100);
alter table
time: 35429.282 ms
postgres=# alter table tbx1 alter column c1 type char(6);
alter table
time: 20004.198 ms
postgres=# alter table tbx1 alter column c1 type char(4);
error: value too long for type character(4)
time: 4.671 ms 

变更char类型,varchar和text类型互转

alter table tbx1 alter column c1 type varchar(6);
alter table
time: 18880.369 ms
postgres=# alter table tbx1 alter column c1 type text;
alter table
time: 12.691 ms
postgres=# alter table tbx1 alter column c1 type varchar(20);
alter table
time: 32846.016 ms
postgres=# alter table tbx1 alter column c1 type char(20);
alter table
time: 39796.784 ms
postgres=# alter table tbx1 alter column c1 type text;
alter table
time: 32091.025 ms
postgres=# alter table tbx1 alter column c1 type char(20);
alter table
time: 26031.344 ms 

定义变更后的数据

定义变更后,数据位置未变,即没有产生新的tuple

postgres=# select ctid,id from tbx1 limit 5;
 ctid | id 
-------+----
 (0,1) | 1
 (0,2) | 2
 (0,3) | 3
 (0,4) | 4
 (0,5) | 5
(5 rows) 

除varchar扩容以外的定义变更,每个tuple产生一条wal记录

$ pg_xlogdump -f -s 3/be002088 -n 5
rmgr: heap    len (rec/tot):   3/  181, tx:    1733, lsn: 3/be002088, prev 3/be001fb8, desc: insert off 38, blkref #0: rel 1663/13269/16823 blk 58358
rmgr: heap    len (rec/tot):   3/  181, tx:    1733, lsn: 3/be002140, prev 3/be002088, desc: insert off 39, blkref #0: rel 1663/13269/16823 blk 58358
rmgr: heap    len (rec/tot):   3/  181, tx:    1733, lsn: 3/be0021f8, prev 3/be002140, desc: insert off 40, blkref #0: rel 1663/13269/16823 blk 58358
rmgr: heap    len (rec/tot):   3/  181, tx:    1733, lsn: 3/be0022b0, prev 3/be0021f8, desc: insert off 41, blkref #0: rel 1663/13269/16823 blk 58358
rmgr: heap    len (rec/tot):   3/  181, tx:    1733, lsn: 3/be002368, prev 3/be0022b0, desc: insert off 42, blkref #0: rel 1663/13269/16823 blk 58358 

结论

varchar扩容,varchar转text只需修改元数据,毫秒完成。

其它转换需要的时间和数据量有关,1000w数据10~40秒,但是不改变数据文件,只是做检查。

缩容时如果定义长度不够容纳现有数据报错

不建议使用char类型,除了埋坑几乎没什么用,这一条不仅适用与pg,所有关系数据库应该都适用。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。如有错误或未考虑完全的地方,望不吝赐教。

(0)
上一篇 2022年3月21日
下一篇 2022年3月21日

相关推荐