我有一个迭代输入并将数据吐出到AWS Firehose的进程,我已将其配置为上传到我创建的redshift表。一个问题是有时行可以重复,因为进程需要重新评估数据。 类似的东西:
Event_date, event_id, event_cost
2015-06-25, 123, 3
2015-06-25, 123, 4
http://docs.aws.amazon.com/redshift/latest/dg/t_updating-inserting-using-staging-tables-.html
在那里,我想用新值替换旧行,如下所示:
insert into event_table_staging
select event_date,event_id, event_cost from <s3 location>;
delete from event_table
using event_table_staging
where event_table.event_id = event_table_staging.event_id;
insert into target
select * from event_table_staging;
delete from event_table_staging
select * from event_table_staging;
是否可以执行以下操作:
Redshift columns: event_date,event_id,cost
copy event_table from <s3>
(update event_table
select c_source.event_date,c_source.event_id,c_source.cost from <s3 source> as c_source join event_table on c_source.event_id = event_table.event_id)
CSV
copy event_table from <s3>
(insert into event_table
select c_source.event_date,c_source.event_id,c_source.cost from event_table left outer join<s3 source> as c_source join on c_source.event_id = event_table.event_id where c_source.event_id is NULL)
CSV
答案 0 :(得分:3)
您无法直接从COPY进行合并。
但是,您的初始方法可以使用临时表包装在事务中,以便为最佳性能分级加载数据。
BEGIN
;
CREATE TEMP TABLE event_table_staging (
event_date TIMESTAMP NULL
,event_id BIGINT NULL
,event_cost INTEGER NULL )
DISTSTYLE KEY
DISTKEY (event_id)
SORTKEY (event_id)
;
COPY event_table_staging
FROM <s3 location>
COMPUDATE ON
;
UPDATE event_table
SET event_date = new.event_date
,event_cost = new.event_cost
FROM event_table AS trg
INNER JOIN event_table_staging AS new
ON trg.event_id = new.event_id
WHERE COALESCE(trg.event_date,0) <> COALESCE(new.event_date,0)
AND COALESCE(trg.event_cost,0) <> COALESCE(new.event_cost,0)
;
INSERT INTO event_table
SELECT event_date
,event_id
,event_cost
FROM event_table_staging AS new
LEFT JOIN event_table AS trg
ON trg.event_id = new.event_id
WHERE trg.event_id IS NULL
;
COMMIT
;
只要您使用交易并且更新总量相对低(单位数%),此方法实际上表现非常出色。唯一需要注意的是,您的目标需要定期VACUUM
- 每月一次对我们来说足够了。
我们每小时对数百万行范围内的几个表进行此操作,即数百万行合并为数百万行的100。对合并表的用户查询仍然表现良好。
答案 1 :(得分:2)
Redshift经过优化,以经济高效的方式处理大量数据,您需要更改一些关于您从其他数据库获得的数据和数据库的想法。
主要概念是您不应该在Redshift中更新数据。您应该将Redshift中的数据视为&#34; Log&#34;。您可以将函数用作INSERT或UPDATE,但它们将限制您可以显着处理的数据量。
您可以通过多种方式处理重复项:
您可以通过管理您正在处理的所有ID中的一些内存中查找表(例如,在ElastiCache上的Redis中)来防止首先写入重复项,如果您已经处理过了
您可以在Redshift中保留重复内容并使用WINDOW函数处理这些记录,这些函数只会占用其中一条记录(例如LAST_VALUE)。
您可以在Redshift中拥有原始事件,并在对DB的查询中进行聚合,而不是将其作为预处理进行。此模式还可以灵活地更改聚合数据的方式。通过这些聚合,Redshift可以非常快,并且几乎不需要预聚合。
如果您仍想要&#34;清洁&#34;和Redshift中的聚合数据一样,您可以UNLOAD使用正确的聚合或WINDOW函数进行某些SQL查询的数据,删除旧表并将数据复制回Redshift。