我有一个关于一个非常大的表(几乎有3000万行)上的ALTER TABLE命令的问题。
其中一列是varchar(255),我想将其大小调整为varchar(40)。
基本上,我想通过运行以下命令来更改我的列:
ALTER TABLE mytable ALTER COLUMN mycolumn TYPE varchar(40);
如果进程很长,我没有问题,但似乎我的表在ALTER table命令期间不再可读。
有没有更聪明的办法?也许添加一个新列,从旧列复制值,删除旧列,最后重命名新列?
注意:我使用PostgreSQL 9.0。
好吧,我可能要迟到了,但是…
在您的情况下,不需要调整列的大小!
Postgres与其他一些数据库不同,它足够聪明,只使用足够的空间来适应字符串(甚至对较长的字符串使用压缩),因此即使您的列声明为VARCHAR(255) -如果您在列中存储40个字符的字符串,空间使用将是40字节+ 1字节的开销。
短字符串(最多126字节)的存储要求是1字节
加上实际的字符串,其中包括大小写中的空格填充
的性格。较长的字符串有4个字节的开销,而不是1个。
长字符串由系统自动压缩,因此
对磁盘的物理要求可能更少。很长的值也是
存储在后台表中,这样它们就不会干扰快速
访问较短的列值。
(http://www.postgresql.org/docs/9.0/interactive/datatype-character.html)
VARCHAR中的大小规范仅用于检查插入的值的大小,它不会影响磁盘布局。事实上,VARCHAR和TEXT字段在Postgres中是以相同的方式存储的。
我正面临着同样的问题,试图将VARCHAR从32截断为8,并得到ERROR:值对于类型字符变化(8)太长。我希望尽可能地接近SQL,因为我使用的是自制的类似于jpa的结构,我们可能不得不根据客户的选择切换到不同的DBMS (PostgreSQL是默认的)。因此,我不想使用修改System表的技巧。
我结束了在ALTER TABLE中使用using语句:
ALTER TABLE "MY_TABLE" ALTER COLUMN "MyColumn" TYPE varchar(8)
USING substr("MyColumn", 1, 8)
正如@raylu指出的那样,ALTER在表上获得了一个排他锁,因此所有其他操作将被延迟,直到它完成。
好吧,我可能要迟到了,但是…
在您的情况下,不需要调整列的大小!
Postgres与其他一些数据库不同,它足够聪明,只使用足够的空间来适应字符串(甚至对较长的字符串使用压缩),因此即使您的列声明为VARCHAR(255) -如果您在列中存储40个字符的字符串,空间使用将是40字节+ 1字节的开销。
短字符串(最多126字节)的存储要求是1字节
加上实际的字符串,其中包括大小写中的空格填充
的性格。较长的字符串有4个字节的开销,而不是1个。
长字符串由系统自动压缩,因此
对磁盘的物理要求可能更少。很长的值也是
存储在后台表中,这样它们就不会干扰快速
访问较短的列值。
(http://www.postgresql.org/docs/9.0/interactive/datatype-character.html)
VARCHAR中的大小规范仅用于检查插入的值的大小,它不会影响磁盘布局。事实上,VARCHAR和TEXT字段在Postgres中是以相同的方式存储的。