この記事の目的は、PostgreSQL DBMSを使用してPHPプロジェクトでデータベース開発を簡素化するツールを示すために、 スキーマキーパーライブラリを例として使用することです。
次の問題に対処します。
- バージョン管理システム(以降-VCS)にデータベース構造のダンプを保存する形式
- ダンプを保存した後、データベース構造の変更を追跡する方法
- データベース構造の変更を競合や巨大な移行ファイルなしで他の環境に転送する方法
- 複数の開発者がプロジェクトで並行作業のプロセスを確立する方法
- データベース構造の変更を本番環境に安全に展開する方法
この記事の情報は、主にPostgreSQLの機能を最大限に活用したいが、データベース内のビジネスロジックの維持に関する問題に直面している開発者に役立ちます。
この記事では、ビジネスロジックをデータベースに保存することの利点や欠点については説明しません。 選択はすでに読者によって行われていると想定されます。
SchemaKeeperは 、 PL / pgSQLで記述されたストアドプロシージャを操作するために設計されています。 他の言語でのテストはそれぞれ行われませんでした。使用はそれほど効果的でも不可能でもないかもしれません。
VCSのデータベース構造のダンプを保存する形式
スキーマキーパーライブラリは、データベースのオブジェクトの構造を個別のテキストファイルとして保存するsaveDump関数を提供します。 出力は、VCSに簡単に追加できるグループ化されたファイルに分割されたデータベース構造を含むディレクトリを作成します。
いくつかの例を使用して、データベースからファイルにオブジェクトを変換することを検討してください。
ファイルコンテンツは、特定のデータベースオブジェクトの構造のテキスト表現です。 たとえば、ストアドプロシージャの場合、ファイルの内容は、 CREATE OR REPLACE FUNCTIONブロックで始まるストアドプロシージャの完全な定義になります。
上記の表からわかるように、ファイルパスには、オブジェクトのタイプ、スキーム、および名前に関する情報が格納されます。 このアプローチにより、データベースのダンプおよびコードレビューの変更を簡単にナビゲートできます。
ストアドプロシージャのソースコードを含むファイルの.sqlが選択されているため、IDEは、ファイルを開くときにデータベースと対話するためのツールを自動的に提供します。
ダンプを保存した後、データベース構造の変更を追跡する方法
VCSに現在のデータベース構造のダンプを保存したら、ダンプの作成後にデータベース構造に変更が加えられたかどうかを確認できます。 スキーマキーパーライブラリは、データベース構造の変更を検出するためのverifyDump関数を提供し、副作用のない差分に関する情報を返します。
別の確認方法は、同じディレクトリを指定してsaveDump関数をsaveDump呼び出し、VCSの変更を確認することです。 データベースのオブジェクトは個別のファイルに保存されるため、VCSは変更されたオブジェクトのみを表示します。 この方法の主な欠点は、ファイルを上書きして変更を確認する必要があることです。
データベース構造の変更を競合や巨大な移行ファイルなしで他の環境に転送する方法
deployDump関数のおかげで、ストアドプロシージャのソースコードは、他のアプリケーションソースコードと同様に編集されます。 ストアドプロシージャの変更は、対応するファイルに変更を加えることで発生します。これは、バージョン管理システムに自動的に反映されます。
たとえば、 publicスキームで新しいストアドプロシージャを作成するには、 public/functionsディレクトリに.sql拡張子を持つ新しいファイルを作成し、 CREATE OR REPLACE FUNCTIONブロックを含むストアドプロシージャのソースコードを配置してから、 deployDump関数を呼び出します。 同様に、ストアドプロシージャが変更および削除されます。 したがって、コードはVCSとデータベースの両方に同時に入力されます。
ストアドプロシージャのソースコードにエラーが表示された場合、 deployDumpは失敗し、例外がスローされます。 deployDumpを使用して、ダンプと現在のデータベースのストアドプロシージャがdeployDumpないことはありません。
新しいストアドプロシージャを作成する場合、正しいファイル名を手動で入力する必要はありません。 ファイルの拡張子が.sqlあれば十分です。 deployDump関数の戻り値から正しい名前を取得し、ファイルの名前を変更するために使用できます。
deployDumpは、追加のアクションなしで関数または戻り値の型のパラメーターを変更しますが、従来のアプローチでは、 DROP FUNCTIONにDROP FUNCTIONを実行し、次にCREATE OR REPLACE FUNCTIONを実行する必要があります。
残念ながら、状況によっては、 deployDumpは変更を自動的に適用できません。 たとえば、少なくとも1つのトリガーによって使用されるトリガー関数が削除された場合。 このような状況は、移行ファイルを使用して手動で解決されます。
スキーマキーパー自体がストアドプロシージャの変更を転送する場合、移行ファイルを使用して構造の残りの変更を転送します。 たとえば、 教義/移行ライブラリが適しています。
構造に変更を加え、起こりうる問題状況を解決するには、 deployDumpを実行する前に移行を適用する必要があります。
移行の操作については、次のセクションで詳しく説明します。
複数の開発者がプロジェクトで並行作業のプロセスを確立する方法
データベースを完全に初期化するためのスクリプトを作成しましょう。開発者はローカルマシンで実行し、ローカルデータベースの構造をVCSに保存されているダンプに合わせます。 ローカルデータベースの初期化を3つのステップに分割します。
base.sqlなどの基本構造を持つファイルをインポートします- 移行の適用
deployDump呼び出し
base.sqlは、その上で移行が適用され、 deployDumpがdeployDumpれる開始点です。 base.sql + + deployDump = 、 base.sql + + deployDump = です。 データベースをゼロから初期化するときにbase.sqlによってbase.sql使用されます。 そのようなファイルはpg_dumpを使用して生成されます。
完全なデータベース初期化refresh.shスクリプトを呼び出しましょう。 開発者のワークフローは次のとおりです。
- 環境で
refresh.shを実行して、現在のデータベース構造を取得する - タスクの作業の開始、新しい機能のニーズに合わせたローカルデータベースの変更(
ALTER TABLE ... ADD COLUMNなど) - タスクの完了後、
saveDump関数を呼び出して、VCSのデータベースに加えられた変更をコミットします refresh.shをrefresh.shからverifyDumpを実行し、移行に含める変更のリストを表示します- 構造の変更を移行ファイルに
verifyDump 、 refresh.shとverifyDump実行します。移行が正しくverifyDumpている場合、 verifyDumpはローカルデータベースと保存されたダンプに違いがないことを示します。
上記のプロセスは、 gitflow原則と互換性がgitflowます。 VCSの各ブランチには独自のバージョンのダンプが含まれており、ブランチがマージされるとダンプがマージされます。 マージは追加のアクションなしで実行されますが、たとえば同じテーブルに対してブランチで変更が行われた場合、競合が発生する可能性があります。
開発ブランチの例を使用して競合状況を考えてみましょう。このブランチから、 branch1とbranch2が分岐します 。これらは、 developerと競合せず、互いに競合しています。 タスクは、 branch1とbranch2をマージして開発することです。 この場合、最初にbranch1をmergeに開発し 、次にdeveloperをbranch2にマージし 、 branch2の競合を解決してから、 branch2をマージして開発することをお勧めします。 競合解決の段階で、 ブランチの移行ファイルを修正して、 マージの結果を含む最終ダンプに一致させる必要がある場合があります。
データベース構造の変更を本番環境に安全に展開する方法
現在のデータベース構造のVCSダンプに存在することにより、必要な構造に正確に準拠しているかどうか実稼働ベースを確認できます。 これにより、開発者が意図したすべての変更が本番ベースに確実に転送されます。
PostgreSQLのDDLはトランザクションに対応しているため、予期しないエラーが発生した場合にROLLBACK 「無痛」になるように、展開順序に従うことをお勧めします。
- トランザクションを開始
- トランザクションですべての移行を実行する
- 同じトランザクションで、
deployDump実行しdeployDump - トランザクションを完了せずに
verifyDump実行しverifyDump 。 エラーがない場合は、 COMMIT実行します。 エラーがある場合、 ROLLBACK実行しROLLBACK
これらの手順は、ゼロダウンタイムを含め、アプリケーションを展開する既存のアプローチに簡単に統合できます。
おわりに
上記の方法のおかげで、「PHP + PostgreSQL」プロジェクトから最大限のパフォーマンスを引き出すことができ、メインアプリケーションコードでのすべてのビジネスロジックの実装と比較して、開発の利便性は比較的小さくなります。 さらに、 PL / pgSQLでのデータ処理は、PHPで記述された同じ機能よりも多くの場合、より透過的に見え、必要なコードが少なくなります。