postgresql 修改字段长度的操作
使用数据库postgresql的时候,有时会遇到字段长度扩展的情况,由于之前已经有数据了,所以只能修改字段长度,不能通过删除再增加的方式。
可以使用如下方式进行
ALTERTABLEyour_table_namealterCOLUMNyour_column_nametypecharactervarying(3000);
通过上面的一句话就可以把你的表中相应的字段的长度修改为3000.
补充:PostgreSQL字符类型长度变更的性能
背景
业务有时会遇到表中的字符型字段的长度不够用的问题,需要修改表定义。但是表里的数据已经很多了,修改字段长度会不会造成应用堵塞呢?
测试验证
做了个小测试,如下
建表并插入1000w数据
postgres=#createtabletbx1(idint,c1char(10),c2varchar(10)); CREATETABLE postgres=#insertintotbx1selectid,'aaaaa','aaaaa'fromgenerate_series(1,10000000)id; INSERT010000000
变更varchar类型长度
postgres=#altertabletbx1alterCOLUMNc2typevarchar(100); ALTERTABLE Time:1.873ms postgres=#altertabletbx1alterCOLUMNc2typevarchar(99); ALTERTABLE Time:12815.678ms postgres=#altertabletbx1alterCOLUMNc2typevarchar(4); ERROR:valuetoolongfortypecharactervarying(4) Time:5.328ms
变更char类型长度
postgres=#altertabletbx1alterCOLUMNc1typechar(100); ALTERTABLE Time:35429.282ms postgres=#altertabletbx1alterCOLUMNc1typechar(6); ALTERTABLE Time:20004.198ms postgres=#altertabletbx1alterCOLUMNc1typechar(4); ERROR:valuetoolongfortypecharacter(4) Time:4.671ms
变更char类型,varchar和text类型互转
altertabletbx1alterCOLUMNc1typevarchar(6); ALTERTABLE Time:18880.369ms postgres=#altertabletbx1alterCOLUMNc1typetext; ALTERTABLE Time:12.691ms postgres=#altertabletbx1alterCOLUMNc1typevarchar(20); ALTERTABLE Time:32846.016ms postgres=#altertabletbx1alterCOLUMNc1typechar(20); ALTERTABLE Time:39796.784ms postgres=#altertabletbx1alterCOLUMNc1typetext; ALTERTABLE Time:32091.025ms postgres=#altertabletbx1alterCOLUMNc1typechar(20); ALTERTABLE Time:26031.344ms
定义变更后的数据
定义变更后,数据位置未变,即没有产生新的tuple
postgres=#selectctid,idfromtbx1limit5; ctid|id -------+---- (0,1)|1 (0,2)|2 (0,3)|3 (0,4)|4 (0,5)|5 (5rows)
除varchar扩容以外的定义变更,每个tuple产生一条WAL记录
$pg_xlogdump-f-s3/BE002088-n5 rmgr:Heaplen(rec/tot):3/181,tx:1733,lsn:3/BE002088,prev3/BE001FB8,desc:INSERToff38,blkref#0:rel1663/13269/16823blk58358 rmgr:Heaplen(rec/tot):3/181,tx:1733,lsn:3/BE002140,prev3/BE002088,desc:INSERToff39,blkref#0:rel1663/13269/16823blk58358 rmgr:Heaplen(rec/tot):3/181,tx:1733,lsn:3/BE0021F8,prev3/BE002140,desc:INSERToff40,blkref#0:rel1663/13269/16823blk58358 rmgr:Heaplen(rec/tot):3/181,tx:1733,lsn:3/BE0022B0,prev3/BE0021F8,desc:INSERToff41,blkref#0:rel1663/13269/16823blk58358 rmgr:Heaplen(rec/tot):3/181,tx:1733,lsn:3/BE002368,prev3/BE0022B0,desc:INSERToff42,blkref#0:rel1663/13269/16823blk58358
结论
varchar扩容,varchar转text只需修改元数据,毫秒完成。
其它转换需要的时间和数据量有关,1000w数据10~40秒,但是不改变数据文件,只是做检查。
缩容时如果定义长度不够容纳现有数据报错
不建议使用char类型,除了埋坑几乎没什么用,这一条不仅适用与PG,所有关系数据库应该都适用。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持毛票票。如有错误或未考虑完全的地方,望不吝赐教。