2009-05-29 9 views
5

Postgresにスキーマがあり、スキーマ・パッチを適用するための良い方法を学びたいと考えています。スキーマ・パッチ・プラクティス

現在、スキーマ、テーブル、シーケンス、関数などを作成する一連のDDLファイルがあります。テスト環境用の人口スクリプトもあります。これらのファイルはすべて開発、テストなどのためにデータベース環境を再現するために使用されます。

私たちのシステムのバージョンに対応するいくつかの「パッチ」ファイルもあります。すなわち、 patches/1.0.0.sql、patches/1.0.1.sqlなどです。これらのファイルは、ステージングデータベースと本番データベースを更新するために使用されます。

このプロセスは今まで私たちのために働いていましたが、社内でスキーマを最適にパッチする方法について議論がありました。

ステージングとプロダクションのスキーマにパッチを当て、データベースのバージョンを管理する方法については、他の人には興味があります。

ありがとうございます!

答えて

3

現時点では、SQL Serverでは、変更を最初にロールバックするスキーマ変更スクリプトを作成します(idempotentlyなので、スキーマ変更がまだ適用されていなくてもロールバックセクションは正常に実行されます)。その後、変更を適用する。 TSQLでは、システムカタログや他のテーブルを見て、テーブル/カラム/インデックス/行がすでに存在するかどうかを確認し、そうでない場合は何もしません。

PostgreSQLでは、単純にどのコマンドをサーバに送ることができますか?しかし、DDLはトランザクションであるため、半分適用されたスキーマの変更は行われません。私は自分の小さなプロジェクトで使い慣れたスキームを非常にうまく使いこなしました(しかし、ここでも私はdev/test dbと "実際の" dbを持っています)。例えば

\echo Rolling back schema change #35 

BEGIN; 

DELETE FROM schema_version WHERE schema_id = 35; 

DROP TABLE IF EXISTS location_coordinates; 
DROP FUNCTION IF EXISTS location_coordinates_populate(); 

END; 

\echo Applying schema change #35 

BEGIN; 

INSERT INTO schema_version(schema_id, description) VALUES(35, 'Add location_coordinates table'); 

CREATE TABLE location_coordinates(
location_id INT PRIMARY KEY REFERENCES location(location_id), 
latitude FLOAT NOT NULL, 
longitude FLOAT NOT NULL, 
earth_coordinates earth NOT NULL, 
box_10miles cube NOT NULL 
); 

GRANT SELECT, INSERT, UPDATE, DELETE ON location_coordinates TO ui; 

CREATE FUNCTION location_coordinates_populate() RETURNS TRIGGER LANGUAGE 'plpgsql' AS $$ 
BEGIN 
    new.earth_coordinates := ll_to_earth(new.latitude, new.longitude); 
    new.box_10miles := earth_box(new.earth_coordinates, 10 * 1609.344); 
    RETURN new; 
END 
$$; 

CREATE TRIGGER location_coordinates_populate BEFORE INSERT OR UPDATE ON location_coordinates 
FOR EACH ROW EXECUTE PROCEDURE location_coordinates_populate(); 

INSERT INTO location_coordinates(location_id, latitude, longitude) 
SELECT location_id, latitude, longitude FROM location WHERE latitude IS NOT NULL AND longitude IS NOT NULL; 

CREATE INDEX location_coordinates_10miles ON location_coordinates USING gist (box_10miles); 

END; 

\echo Done 

このスクリプトは、 "psql -f schema-changes/35.sql"を使用してデータベース上で実行できます。 "適用中"のメッセージを切り取るだけで、私はそれをロールバックするコマンドを得ることができます。ご覧のとおり、変更によってメタデータテーブル "schema_version"が保持されるので、どの変更が適用されているかが分かります。変更全体は、トランザクション、データ移行、およびすべてとして行われます。ここでは、DROPコマンドの "IF EXISTS"機能を使用して、変更が適用されていなくてもロールバック・セクションを幸せにしました。私たちがOracleの仕事でしたことの1つは、PL/SQLとしてスキーマの変更を書き込んでいたことです.plpgsqlに変更を加えるための機能がいくつかあるでしょうか?

上記の変更では、「場所」から「緯度」および「経度」列(null値)を別の「location_coordinates」関係に移行していることに注意してください(そして地球距離のものを追加してください)私は古い列を落とさなかった。可能であれば、スキーマの変更を後方互換にすることを慎重にする必要があります。だから私はこのスキーマの変更を適用することができます新しいテーブルを使用するようにアプリケーションを更新する前に。のアプリを更新した後に、古い列を削除してを適用するようにもう一度変更する必要があります。作業中は、これらは2つの異なるリリースサイクルで行われるため、リリースXでは、最初にすべてのスキーマの変更をロールバックすることなく、X-1をリリースするためにアプリをロールバックするオプションがあります。アプリケーションの前に別のウィンドウにスキーマの変更を展開することができます。 (技術的には、古いテーブルの更新が新しいテーブルに同期されるようにトリガーを書いたはずですが、それはあまり仕事に似ているからです:))

また、データベースを参照してschema_versionテーブルの内容を確認し、変更を追跡することで、接続しなくてもどのような変更が行われたかを知ることができ、各変更の履歴を知ることができます( "devでロールバック"、 " dev "など)。職場では、schema_versionテーブルにも著者情報などが含まれています。バージョン管理からバージョン情報を適用するという魔法の方法はクールです。SCがQAに適用されると、PERFORCEで変更されます - 1つの通知。したがって、スキーマの変更を追跡する方法は、リビジョン#4が適用されていると良いでしょう。

私たちのためのスキーマの変更には、アプリケーションのバージョンとは無関係に番号が付けられています。明らかにそれらは関連しています---それは、スパイダーアプリが人々に入力できる別のものです---しかし、我々は巨大な "ここにはリリースXのすべての"パッチではなく、小さな変更がたくさんあるようにしています。スキーマの変更は、新しいインデックスの追加などにも使用されるため、アプリ駆動型ではない可能性があります。上記の「インデックス作成」の例では、DBAは基本的に開発者ロールで動作し、スキーマの変更を所有していますが、スキーマの変更はDBAではなく開発者によって「所有」されています。はい、私たちは、開発者からの高いレベルのSQL能力を求めていますが、同社の他のグループは少し違った働きをしてDBチームにもっと多くの仕事を提供しています。

+0

ありがとうアラジン。私たちの会社でも、開発者の役割には適切なスキーマパッチの作成も含まれます。実際にパッチを処理するには、単一のプロセスが使用されます。 私はschema_versionテーブルの考え方が気に入っています。私は職場でそれを議論しました。 – chadl

関連する問題