1. 程式人生 > 資料庫 >postgresql 修改欄位長度的操作

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,lsn: 3/BE002140,prev 3/BE002088,desc: INSERT off 39,lsn: 3/BE0021F8,prev 3/BE002140,desc: INSERT off 40,lsn: 3/BE0022B0,prev 3/BE0021F8,desc: INSERT off 41,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,所有關係資料庫應該都適用。

以上為個人經驗,希望能給大家一個參考,也希望大家多多支援我們。如有錯誤或未考慮完全的地方,望不吝賜教。