我有一个关于一个非常大的表(几乎有3000万行)上的ALTER TABLE命令的问题。 其中一列是varchar(255),我想将其大小调整为varchar(40)。 基本上,我想通过运行以下命令来更改我的列:

ALTER TABLE mytable ALTER COLUMN mycolumn TYPE varchar(40);

如果进程很长,我没有问题,但似乎我的表在ALTER table命令期间不再可读。 有没有更聪明的办法?也许添加一个新列,从旧列复制值,删除旧列,最后重命名新列?

注意:我使用PostgreSQL 9.0。


当前回答

如果你把alter放到一个事务中,表不应该被锁定:

BEGIN;
  ALTER TABLE "public"."mytable" ALTER COLUMN "mycolumn" TYPE varchar(40);
COMMIT;

这对我来说非常有效,几秒钟就搞定了400,000多行。

其他回答

好吧,我可能要迟到了,但是…

在您的情况下,不需要调整列的大小!

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中是以相同的方式存储的。

添加新列,用旧列替换新列,在redshift postgresql上为我工作,更多详细信息请参阅此链接https://gist.github.com/mmasashi/7107430

BEGIN;
LOCK users;
ALTER TABLE users ADD COLUMN name_new varchar(512) DEFAULT NULL;
UPDATE users SET name_new = name;
ALTER TABLE users DROP name;
ALTER TABLE users RENAME name_new TO name;
END;

如果你把alter放到一个事务中,表不应该被锁定:

BEGIN;
  ALTER TABLE "public"."mytable" ALTER COLUMN "mycolumn" TYPE varchar(40);
COMMIT;

这对我来说非常有效,几秒钟就搞定了400,000多行。

试着运行下面的alter表:

ALTER TABLE public.users 
ALTER COLUMN "password" TYPE varchar(300) 
USING "password"::varchar;

我发现了一个非常简单的方法来改变大小,即注释@Size(min = 1, max = 50),这是import javax.validation的一部分。约束”。 “进口javax.validation.constraints.Size;”

@Size(min = 1, max = 50)
private String country;


when executing  this is hibernate you get in pgAdmin III 


CREATE TABLE address
(
.....
  country character varying(50),

.....

)