AWS Redshiftをテストしただけで、キー列の重複で失敗することを望んでいた挿入でいくつかの重複データを発見したので、ドキュメントを読むと、主キーの制約が「強制」されていないことがわかります。
誰もが主キーの重複を防ぐ方法を見つけました(「従来の」期待による)。
Redshift のパイオニアに感謝します。
AWS Redshiftをテストしただけで、キー列の重複で失敗することを望んでいた挿入でいくつかの重複データを発見したので、ドキュメントを読むと、主キーの制約が「強制」されていないことがわかります。
誰もが主キーの重複を防ぐ方法を見つけました(「従来の」期待による)。
Redshift のパイオニアに感謝します。
レコードの作成時に UUID を割り当てます。レコードが本質的に一意である場合は、タイプ 4 の UUID (ランダム) を使用し、そうでない場合は、入力として自然キーを使用してタイプ 5 (SHA-1 ハッシュ) を使用します。
次に、AWS によるこの指示に従って、非常に簡単に UPSERT を実行できます。入力に重複がある場合は、ステージング テーブルで次のような SQL を発行することでクリーンアップできるはずです。
CREATE TABLE cleaned AS
SELECT
pk_field,
field_1,
field_2,
...
FROM (
SELECT
ROW_NUMBER() OVER (PARTITION BY pk_field order by pk_field) AS r,
t.*
from table1 t
) x
where x.r = 1
行 ID として使用する ID 列を追加するのが遅すぎる場合 ( Redshift で列ALTER
を追加することはできません)、次のようにすることができます。IDENTITY
DISTINCT
重複を取り除くために使用します)。ここにサンプルid
があります:(が重複をチェックするためのキーであり、data_table
があなたのテーブルであると仮定しましょう)
CREATE TEMP TABLE delete_dupe_row_list AS
SELECT t.id FROM data_table t WHERE t.id IS NOT NULL GROUP BY t.id HAVING COUNT(t.id)>1;
CREATE TEMP TABLE delete_dupe_rows AS
SELECT DISTINCT d.* FROM data_table d JOIN delete_dupe_row_list l ON l.id=d.id;
START TRANSACTION;
DELETE FROM data_table USING delete_dupe_row_list l WHERE l.id=data_table.id;
INSERT INTO data_table SELECT * FROM delete_dupe_rows;
COMMIT;
DROP TABLE delete_dupe_rows;
DROP TABLE delete_dupe_row_list;
確認された、彼らはそれを強制しません:
一意性、主キー、および外部キーの制約は情報提供のみを目的としています。それらは Amazon Redshift によって強制されません。それにもかかわらず、主キーと外部キーは計画のヒントとして使用され、ETL プロセスまたはアプリケーションの他のプロセスがそれらの整合性を強制する場合は宣言する必要があります。
たとえば、クエリ プランナーは、特定の統計計算で主キーと外部キーを使用して、サブクエリの非相関手法に影響を与える一意性と参照関係を推測し、多数の結合を並べ替え、冗長な結合を排除します。
プランナーはこれらのキーの関係を利用しますが、Amazon Redshift テーブルのすべてのキーが読み込まれた時点で有効であると想定しています。アプリケーションで無効な外部キーまたは主キーが許可されている場合、一部のクエリで誤った結果が返される可能性があります。たとえば、主キーが一意でない場合、SELECT DISTINCT クエリは重複する行を返す可能性があります。テーブルの有効性が疑わしい場合は、テーブルのキー制約を定義しないでください。一方、有効であることがわかっている場合は、主キーと外部キー、および一意性制約を常に宣言する必要があります。
Amazon Redshift は NOT NULL 列の制約を適用します。
http://docs.aws.amazon.com/redshift/latest/dg/t_Defining_constraints.html
手早く汚い方法は group by を使うことです
select max(<column_a>), max(<column_a>), <pk_column1>, <pk_column2>
from <table_name>
group by <pk_column1>, <pk_column2>
Yeah You can not do that. For the time being, I think you should just insert duplicate data(basically duplicate keys) with an extra column of timestamp. So it will have all versions of that particular row, since update is also an insert and while you query Redshift, make sure you pick the latest one.