Скопируйте данные из Amazon S3 в Redshift и избегайте дублирования строк

я копирую данные из Amazon S3 в Redshift. Во время этого процесса мне нужно избежать повторной загрузки тех же файлов. У меня нет никаких ограничений на моем столе красного смещения. Есть ли способ реализовать это с помощью команды "копировать"?

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

Я попытался добавить уникальное ограничение и установить столбец в качестве первичного ключа без успеха. Красное смещение не поддерживает ограничения unique/primary key.

4 ответов


мое решение-запустить команду "удалить" перед "копировать" в таблице. В моем случае использования каждый раз, когда мне нужно скопировать записи ежедневного снимка в таблицу redshift, поэтому я могу использовать следующую команду "Удалить", чтобы убедиться, что дублированные записи удалены, а затем запустить команду "копировать".

удалить из t_data, где snapshot_day = 'xxxx-xx-xx';


как упоминал user1045047, Amazon Redshift не поддерживает уникальные ограничения, поэтому я искал способ удаления дубликатов записей из таблицы с помощью инструкции delete. Наконец, я нашел разумный способ.

Amazon Redshift поддерживает создание столбца идентификаторов, в котором хранится автоматически сгенерированный уникальный номер. http://docs.aws.amazon.com/redshift/latest/dg/r_CREATE_TABLE_NEW.html

следующий sql предназначен для удаления PostgreSQL дублированные записи с OID, который является уникальным столбцом, и вы можете использовать этот sql, заменив OID столбцом identity.

DELETE FROM duplicated_table WHERE OID > (
 SELECT MIN(OID) FROM duplicated_table d2
  WHERE column1 = d2.dupl_column1
  AND column2 = d2.column2
);

вот пример, который я тестировал на своем кластере 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)

также он работает с командой копирования, как это.

  • auto_id_table.csv

    John,18
    Bob,20
    Matt,24
    
  • копировать sql

    copy auto_id_table (name, age) from '[s3-path]/auto_id_table.csv' CREDENTIALS 'aws_access_key_id=[your-aws-key-id] ;aws_secret_access_key=[your-aws-secret-key]' delimiter ','; 
    

преимущество этого способа заключается в том, что вам не нужно запускать DDL заявления. Однако он не работает с существующими таблицами, у которых нет столбца идентификаторов, поскольку столбец идентификаторов нельзя добавить в существующую таблицу. Единственный способ удалить дублированные записи с существующими таблицами-это перенести все записи таким образом. (то же, что и ответ user1045047)

insert into temp_table (select distinct from original_table);
drop table original_table;
alter table temp_table rename to original_table;

МММ..

Как насчет того, чтобы просто никогда не загружать данные в главную таблицу напрямую.

меры, чтобы избежать дублирования:

  1. начать транзакцию
  2. массовая загрузка в временную промежуточную таблицу
  3. удалить из главной таблицы, где строки = промежуточная таблица строк
  4. вставить в главную таблицу из промежуточной таблицы (merge)
  5. drop промежуточная таблица
  6. конец сделки.

Это тоже супер несколько быстро и рекомендуется Redshift docs.


В настоящее время нет способа удалить дубликаты из redshift. Redshift не поддерживает ограничения первичного ключа/уникального ключа, а также удаление дубликатов с использованием номера строки не является опцией (удаление строк с номером строки больше 1), поскольку операция удаления при redshift не допускает сложных операторов (также понятие номера строки отсутствует в redshift).

лучший способ удалить дубликаты-написать задание cron / quartz, которое будет выбирать все отдельные строки, помещать их в отдельной таблице, а затем переименуйте таблицу в исходную таблицу.

Insert into temp_originalTable (Select Distinct from originalTable)

Drop table originalTable

Alter table temp_originalTable rename to originalTable