将数据从Amazon S3复制到Redshift并避免重复行

Rup*_*lia 9 copy amazon-s3 duplicates amazon-web-services amazon-redshift

我正在将数据从Amazon S3复制到Redshift.在此过程中,我需要避免再次加载相同的文件.我的Redshift表没有任何独特的限制.有没有办法使用copy命令实现它?

http://docs.aws.amazon.com/redshift/latest/dg/r_COPY_command_examples.html

我尝试添加唯一约束和设置列作为主键,没有运气.Redshift似乎不支持唯一/主键约束.

Mas*_*aki 15

正如user1045047所述,Amazon Redshift不支持唯一约束,因此我一直在寻找使用delete语句从表中删除重复记录的方法.最后,我找到了一个合理的方法.

Amazon Redshift支持创建存储自动生成的唯一编号的IDENTITY列. http://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html

以下sql用于PostgreSQL删除具有唯一列的OID的重复记录,您可以通过将OID替换为标识列来使用此sql.

DELETE FROM duplicated_table WHERE OID > (
?SELECT MIN(OID) FROM duplicated_table d2
??WHERE column1 = d2.dupl_column1
??AND column2 = d2.column2
);
Run Code Online (Sandbox Code Playgroud)

以下是我在Amazon Redshift群集上测试的示例.

create table auto_id_table (auto_id int IDENTITY, name varchar, age int);

insert into auto_id_table (name, age) values('John', 18);
insert into auto_id_table (name, age) values('John', 18);
insert into auto_id_table (name, age) values('John', 18);
insert into auto_id_table (name, age) values('John', 18);
insert into auto_id_table (name, age) values('John', 18);
insert into auto_id_table (name, age) values('Bob', 20);
insert into auto_id_table (name, age) values('Bob', 20);  
insert into auto_id_table (name, age) values('Matt', 24); 

select * from auto_id_table order by auto_id; 
 auto_id | name | age 
---------+------+-----
       1 | John |  18
       2 | John |  18
       3 | John |  18
       4 | John |  18
       5 | John |  18
       6 | Bob  |  20
       7 | Bob  |  20
       8 | Matt |  24    
(8 rows) 

delete from auto_id_table where auto_id > (
  select min(auto_id) from auto_id_table d
    where auto_id_table.name = d.name
    and auto_id_table.age = d.age
);

select * from auto_id_table order by auto_id;
 auto_id | name | age 
---------+------+-----
       1 | John |  18
       6 | Bob  |  20
       8 | Matt |  24
(3 rows)
Run Code Online (Sandbox Code Playgroud)

它也可以像这样使用COPY命令.

这种方式的优点是您不需要运行DDL语句.但是,它不适用于没有标识列的现有表,因为无法将标识列添加到现有表中.使用现有表删除重复记录的唯一方法是迁移所有这样的记录.(与user1045047的答案相同)

insert into temp_table (select distinct from original_table);
drop table original_table;
alter table temp_table rename to original_table;
Run Code Online (Sandbox Code Playgroud)

  • 我不清楚你的`copy sql`是如何表明它正确处理重复的.对于你正在加载的数据集`audo_id_table.csv`,它只有3个唯一的行,不是吗? (3认同)

Kyl*_*bel 6

嗯..

那么永远不要直接将数据加载到主表中.

避免重复的步骤:

  1. 开始交易
  2. 批量加载到临时临时表中
  3. 从主表中删除rows = staging table rows
  4. 从登台表插入主表(合并)
  5. 下降临时表
  6. 结束交易.

这也是 有点快,并由redshift docs推荐.

  • 问题是当临时表有重复记录时。 (3认同)
  • 你能否详细说明这个答案的"这也是超快速"的一部分?我们有一个数十亿行的表,我们使用亚马逊文档推荐的这种方法,但除非我们做错了,否则它肯定不会超快.这是迄今为止我们ETL过程的瓶颈. (2认同)

cip*_*hor 5

我的解决方案是在表上的'copy'之前运行'delete'命令.在我的用例中,每次我需要将每日快照的记录复制到redshift表时,我可以使用以下'delete'命令来确保删除重复的记录,然后运行'copy'命令.

从t_data删除其中snapshot_day ='xxxx-xx-xx';