web-dev-qa-db-ja.com

ダウンタイムなしでのスキーマ変更とライブデータベースへのデータ移行のベストプラクティス

ダウンタイムなしでライブデータベースのスキーマをどのように変更しますか?

たとえば、特定のユーザーに関連付けられた、メールアドレスなどのさまざまなユーザーデータを含むテーブルを含むPostgreSQLデータベースがあるとします。電子メールアドレスを新しい専用テーブルに移動したい場合は、スキーマを変更してから、電子メールデータを新しいテーブルに移行する必要があります。元のテーブルへの書き込みを停止せずにこれを行うにはどうすればよいですか?確かに、古いテーブルから新しいテーブルにデータが上書きされている間、新しいデータは引き続き古いテーブルに書き込まれ、失われますよね?

この問題はかなり頻繁に発生すると思いますが、それを処理するための標準的な解決策を見つけることができません。

この記事 は問題を扱いますが、ステップ3を本当に理解していませんでした。彼は両方のテーブルに書き込み、古いデータを最初のテーブルから新しいテーブルに移行するように言っています。古いデータのみを移行していることをどのように確認しますか?

(私は PostgreSQL on Herok を使用します。)

44
Dan Leary

あなたはもうほとんど答えを持っています:

  1. 新しい構造を並行して作成する
  2. 両方の構造への書き込みを開始します
  3. 古いデータを新しい構造に移行する
  4. 新しい構造の書き込みと読み取りのみ
  5. 古い列を削除する

ステップについては、次のようなものを使用します(1つのトランザクションで)。

まだ存在しないものを挿入します。

INSERT INTO new_tbl (old_id, data)
SELECT old_id, data
FROM   old_tbl
WHERE  NOT EXISTS (SELECT * FROM new_tbl WHERE new_tbl.old_id = old_tbl.old_id);

その間に変更された内容を更新します。

UPDATE new_tbl
SET    data  = old.data
USING  old_tbl
WHERE  new_tbl.old_id = old_tbl.old_id
AND    new_tbl.data IS DISTINCT FROM old_tbl.data;

新しいデータは両方の場所で同一であるため、変更されません。

27