将现有的SMALLINT数据转换为INTEGER?

时间:2012-11-19 22:52:47

标签: postgresql

我在Postgres有一张表,行数约为1M。此表中的一列存储SMALLINT数据。现在我需要在此列中存储大于我预期的数字。如何将此现有列从SMALLINT转换为INTEGER?

2 个答案:

答案 0 :(得分:7)

您需要将列数据类型从smallint更改为integer

alter table T alter C type integer

T和C分别是表名和列名。

  

设置数据类型

     

此表单更改表的列类型。索引和简单表约束   涉及列将自动转换为使用新列类型   重新分析最初提供的表达式。可选的COLLATE子句指定了一个   新列的整理;如果省略,则排序规则是新列的默认值   类型。可选的USING子句指定如何从中计算新列值   旧;如果省略,则默认转换与从旧数据转换的赋值相同   键入新的。如果没有隐式或赋值转换,则必须提供USING子句   从旧到新。

请参阅ALTER TABLE文档。

答案 1 :(得分:3)

正如Ondrej所说,你可以使用ALTER TABLE .. ALTER COLUMN ... TYPE INTEGER

但是,这将触发一个完整的表重写,锁定表以防止所有并发写入或读取持续时间。这对于大型表来说可能非常耗时。

如果您需要避免这种情况,您可以分阶段进行更改。

  • BEGIN,添加一个新的整数列和COMMIT
  • BEGIN一个事务,LOCK TABLE ... IN EXCLUSIVE MODE阻止并发插入。
  • UPDATE表格,将smallint数据复制到integer列。
  • 现在删除smallint列,将integer列重命名为smallint的名称,然后COMMIT

如果您愿意编写将LOCK TABLE列中的值复制到BEFORE INSERT OR UPDATE ON ... FOR EACH ROW的{​​{1}}触发器,您甚至可以避免smallint并允许并发写入任何integerINSERT上的列。您需要在创建新整数列的同一事务中添加此触发器,以便捕获与您的大UPDATE同时添加的行。为了进一步减少更改对应用程序的影响,您可以在单个事务中以小批量更新行,这样可以避免长行锁定。

我写了更多关于这个in this prior dba.SE answer