こんにちは。データサイエンティスト兼、データ基盤エンジニアのshobyです。
今回は、RedShiftの制約について注意すべき点をご紹介します。
概要
- RedShiftの制約は違反できる
- DataPipelineを使った実質的なPrimary Key制約の実現
RedShiftの制約は違反できる
いきなり結論からですが、NOT NULL制約以外のRedShiftの制約は違反することができます。
プライマリキー制約やユニークキー制約を無視して同一のキーを持つレコードをINSERTすることができますし、外部キー制約を無視してデータを入れることができます。
プライマリーキー制約、ユニークキー制約、外部キー制約はクエリプランナーによる実行計画の最適化のみに使われ、データの整合性は維持してくれません。 *1
RedShiftは追記型のデータウェアハウスとして使うことが多く、 別途存在するオリジナルのデータソースからbatchでデータを流し込むことが多いため、 INSERTをするだけであれば、運用でカバーをすることができます。
問題が起きやすいのがPrimary Keyを使い、 コードがなければINSERT、レコードがあればUPDATEという処理を書く場合です。
RedShiftにはPostgreSQLのUPSERT文がなく、 Primary Key制約にも違反することができてしまうため、 処理が複雑になってしまいがちです。
この問題に対しては、AWSのDatapipelineを用いることで対応することができます。
DataPipelineを使った実質的なPrimary Key制約の実現
DataPipelineとは、データの移動や変換を行うためのサービスです。
多機能なETLサービスであるAWS Glueと比べ、 データソース間のデータ転送に特化したシンプルな機能が提供されています。
このDataPipelineの機能を用いることで、 実質的にPrimary Keyを使ったUPSERTを行うことができます。
RedshiftCopyActivityのOVERWRITE_EXISTINGオプション
RedshiftCopyActivityというRedShiftへのデータコピーを行うActivityには、 OVERWRITE_EXISTINGというオプションが存在します。
このオプションを設定した場合、 Primary Keyが一致する行があればUPDATEで上書きされ、 なければINSERTが行われます。
これにより、Primary Key制約を用いて、UPSERTを実現することができます。
まとめ
RedShiftではプライマリーキー制約、ユニークキー制約、外部きー制約には違反をすることができるため、データのINSERT時には気をつける必要があります。
Primary Keyを用いたUPSERTを行いたい場合には、 DataPipelineのRedshiftCopyActivityのOVERWRITE_EXISTINGオプションを用いることで、 実質的なUPSERTを行うことができます。
*1:おそらく、各データがクラスター内のノードに分散して配置されるため、整合性を保つ上場合はパフォーマンスの維持が難しいのだと思われます。