在Amazon Redshift中更改列数据类型


85

如何更改Amazon Redshift数据库中的列数据类型?

我无法在Redshift中更改列数据类型;有什么方法可以修改Amazon Redshift中的数据类型?


6
“创建表为选择...”,然后使用更好的列类型设计新表。
盖伊

Answers:


135

ALTER TABLE文档中所述,您可以VARCHAR使用

ALTER TABLE table_name
{
    ALTER COLUMN column_name TYPE new_data_type 
}

对于其他列类型,我能想到的就是添加具有正确数据类型的新列,然后将旧列中的所有数据插入到新列中,最后删除旧列。

使用类似于以下代码:

ALTER TABLE t1 ADD COLUMN new_column ___correct_column_type___;
UPDATE t1 SET new_column = column;
ALTER TABLE t1 DROP COLUMN column;
ALTER TABLE t1 RENAME COLUMN new_column TO column;

将会发生模式更改-新添加的列将位于表的最后(这可能是COPY语句的问题,请记住这一点-您可以使用定义列顺序COPY


4
更改或就此而言,无论DDL语句是否包装在事务中,都将立即提交。
Raniendu Singh

@RanienduSingh一些数据库确实支持事务性DDL语句。我还没有找到权威列表,但是Redshift中的大多数DDL语句似乎都可以在事务中工作。但是,我认为对与此处描述的方法(重命名,添加,更新,删除)相似的操作进行重新排序可能会更可靠:simple.com/engineering/safe-migrations-with-redshift
Matt Good

1
值得一提的是,现在有可能增加VARCHAR列的大小-见下文user0000的答案,并链接到文档(docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE.html
威利斯

1
@Tomasz Tybulewicz您能否更新您的答案,包括user0000的答案?您的回答当时是正确的,但我误导了我。幸运的是,我也阅读了user0000的答案
Vzzarr,

43

为了避免Tomasz提到的架构更改:

BEGIN TRANSACTION;

ALTER TABLE <TABLE_NAME> RENAME TO <TABLE_NAME>_OLD;
CREATE TABLE <TABLE_NAME> ( <NEW_COLUMN_DEFINITION> );
INSERT INTO <TABLE_NAME> (<NEW_COLUMN_DEFINITION>)
SELECT <COLUMNS>
FROM <TABLE_NAME>_OLD;
DROP TABLE <TABLE_NAME>_OLD;

END TRANSACTION;

1
这也是我们为了避免复制语句未对齐而使用的方法。
smb

1
请记住,用于从旧表中进行选择的所有视图都将继续指向旧表。该drop table查询将显示哪些可以,但不应该被忽略的相关性错误。

1
谢谢,这真的很有帮助。我在具有3100万行的表上使用了它,使用dc1.large类型只花了3分钟。大!我还使用了一个稍微简单的形式:INSERT INTO <TABLE_NAME> SELECT * FROM <TABLE_NAME>_OLD;
汤姆(Tom),

用TRANSACTION封装非常重要
louis_guitton

16

(最新更新)可以在Redshift中更改varchar列的类型。

ALTER COLUMN column_name TYPE new_data_type

例:

CREATE TABLE t1 (c1 varchar(100))

ALTER TABLE t1 ALTER COLUMN c1 TYPE varchar(200)

这是文档链接


这很完美。一个很好的衬里,它根本不会更改架构,但会更新数据类型。这应该是新的更新答案!
蒂莫西·麦克威廉姆斯

8

如果您不想更改列顺序,则可以选择创建一个临时表,然后拖放并创建具有所需大小的新表,然后再次批量处理数据。

CREATE TEMP TABLE temp_table AS SELECT * FROM original_table;
DROP TABLE original_table;
CREATE TABLE original_table ...
INSERT INTO original_table SELECT * FROM temp_table;

重新创建表的唯一问题是您将需要再次授予权限,如果表太大,则将花费一些时间。


1
这与Wolli现有的答案很相似,即重命名然后将旧表数据复制到新架构中。两者都将保持列顺序,但是这种使用临时表的解决方案需要将数据复制两次。一次复制到临时表中,另一次复制回新表中。仅执行一个副本即可重命名表。
马特·古德

4
ALTER TABLE publisher_catalogs ADD COLUMN new_version integer;

update publisher_catalogs set new_version = CAST(version AS integer);
ALTER TABLE publisher_catalogs DROP COLUMN version RESTRICT;
ALTER TABLE publisher_catalogs RENAME new_version to version;

3

Redshift是列式数据库,不允许您直接修改数据类型,但是下面是一种可更改列顺序的方法。

脚步 -

1.Alter表将newcolumn添加到表中2.用oldcolumn值更新newcolumn值3.Alter表以删除oldcolumn 4.alter表将列重命名为oldcolumn

如果您不想更改列的顺序,那么解决方案是

1.使用新列名称创建临时表

  1. 将数据从旧表复制到新表。

  2. 放下旧桌子

  3. 将新表重命名为旧表

  4. 重要的事情是使用like命令而不是简单的create创建一个新表。


2

此方法适用于将(大)int列转换为varchar

-- Create a backup of the original table
create table original_table_backup as select * from original_table;

-- Drop the original table, and then recreate with new desired data types
drop table original_table;

create table original_table (
  col1 bigint,
  col2 varchar(20) -- changed from bigint
);

-- insert original entries back into the new table
insert into original_table select * from original_table_backup;

-- cleanup
drop original_table_backup;

0

使用表重命名策略的UNLOADCOPY应该是最有效的方法如果保留表结构(行顺序)很重要,则执行此操作。

这是添加到此答案的示例。

BEGIN TRANSACTION;

ALTER TABLE <TABLE_NAME> RENAME TO <TABLE_NAME>_OLD;
CREATE TABLE <TABLE_NAME> ( <NEW_COLUMN_DEFINITION> );
UNLOAD ('select * from <TABLE_NAME>_OLD') TO 's3://bucket/key/unload_' manifest;
COPY <TABLE_NAME> FROM 's3://bucket/key/unload_manifest'manifest;

END TRANSACTION;

-2

用于在redshift中更新同一列,这将正常工作

UPDATE table_name 
SET column_name = 'new_value' WHERE column_name = 'old_value'

您可以通过使用and在where中有多个子句,从而消除sql的任何混乱

干杯!!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.