我在Postgres有一张表,行数约为1M。此表中的一列存储SMALLINT数据。现在我需要在此列中存储大于我预期的数字。如何将此现有列从SMALLINT转换为INTEGER?
答案 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
并允许并发写入任何integer
或INSERT
上的列。您需要在创建新整数列的同一事务中添加此触发器,以便捕获与您的大UPDATE
同时添加的行。为了进一步减少更改对应用程序的影响,您可以在单个事务中以小批量更新行,这样可以避免长行锁定。
我写了更多关于这个in this prior dba.SE answer。