将NOT NULL列添加到Redshift表

时间:2016-10-07 10:10:57

标签: amazon-redshift

我想在一个Redshift表中添加一个NOT NULL列,该表包含记录,一个IDENTITY字段,以及其他表有外键。

在PostgreSQL中,您可以将列添加为NULL,将其填入,然后将其更改为NOT NULL。

在Redshift中,到目前为止我发现的最好的是:

ALTER TABLE my_table ADD COLUMN new_column INTEGER;

-- Fill that column

CREATE TABLE my_table2 (
    id INTEGER IDENTITY NOT NULL SORTKEY,
    (... all the fields ... )
    new_column INTEGER NOT NULL,
    PRIMARY KEY(id)
) DISTSTYLE all;

UNLOAD  ('select * from my_table')
to 's3://blah' credentials '<aws-auth-args>' ;

COPY my_table2 
from 's3://blah' credentials '<aws-auth-args>'
EXPLICIT_IDS;

DROP table my_table;

ALTER TABLE my_table2 RENAME TO my_table;

-- For each table that had a foreign key to my_table:
ALTER TABLE another_table ADD FOREIGN KEY(my_table_id) REFERENCES my_table(id)

这是实现这一目标的最佳方法吗?

1 个答案:

答案 0 :(得分:0)

您无需加载到S3就可以实现此目的。

  1. 修改现有表以创建具有默认值的所需列
  2. 以某种方式更新该列(在我的情况下是从另一列复制)
  3. 使用没有默认值的列创建新表
  4. 插入新表中(您必须列出列而不是使用(*),因为顺序可能相同(例如,是否要将新列放在位置2)
  5. 放下旧桌子
  6. 重命名表
  7. 更改表以提供正确的所有者(如果适用)

例如:

-- first add the column w/ a default value
alter table my_table_xyz
    add visit_id bigint NOT NULL default 0; -- not null but default value

-- now populate the new column with whatever is appropriate (the key in my case)
update my_table_xyz
set visit_id = key;

-- now create the new table with the proper constraints
create table my_table_xzy_new
(
    key bigint not null,
    visit_id bigint NOT NULL, -- here it is not null and no default value
    adt_id bigint not null
);

-- select all from old into new
insert into my_table_xyz_new
select key, visit_id, adt_id
from my_table_xyz;

-- remove the orig table
DROP table my_table_xzy_events;

-- rename the newly created table to the desired table
alter table my_table_xyz_new rename to my_table_xyz;

-- adjust any views, foreign keys or permissions as required