質問

DB スキーマの変更を追跡および/または自動化するための最良の方法は何ですか?私たちのチームはバージョン管理に Subversion を使用しており、この方法で一部のタスク (ビルドをステージング サーバーにプッシュし、テスト済みのコードを運用サーバーにデプロイする) を自動化できましたが、データベースの更新は依然として手動で行っています。コードと DB の更新をさまざまなサーバーにプッシュするバックエンドとして Subversion を使用し続けながら、異なる環境のサーバー間で効率的に作業できるソリューションを見つけるか作成したいと考えています。

多くの一般的なソフトウェア パッケージには、DB バージョンを検出し、必要な変更を適用する自動更新スクリプトが含まれています。これは、より大規模な (複数のプロジェクト、場合によっては複数の環境や言語にわたる) 場合でもこれを行う最善の方法ですか?もしそうなら、プロセスを簡素化する既存のコードはありますか、それとも独自のソリューションを展開するのが最善ですか?誰かが以前に同様のものを実装し、それを Subversion のコミット後のフックに統合したことがありますか、それともこれは悪いアイデアですか?

複数のプラットフォームをサポートするソリューションが望ましいですが、作業の大部分は Linux/Apache/MySQL/PHP スタックで行われるため、必ず Linux/Apache/MySQL/PHP スタックをサポートする必要があります。

役に立ちましたか?

解決

Rails の世界には移行という概念があり、データベースへの変更をデータベース固有の SQL ではなく Ruby で行うスクリプトです。Ruby 移行コードは、最終的に現在のデータベースに固有の DDL に変換されます。これにより、データベース プラットフォームの切り替えが非常に簡単になります。

データベースに変更を加えるたびに、新しい移行を作成します。移行には通常、次の 2 つの方法があります。変更を適用する「アップ」メソッドと、変更を元に戻す「ダウン」メソッドです。1 つのコマンドでデータベースを最新の状態にでき、データベースを特定のバージョンのスキーマにするために使用することもできます。Rails では、移行はプロジェクト ディレクトリ内の独自のディレクトリに保存され、他のプロジェクト コードと同様にバージョン管理にチェックインされます。

Rails 移行に関する Oracle ガイド 移行を非常によくカバーしています。

他の言語を使用している開発者は移行を検討し、独自の言語固有のバージョンを実装しています。私は知っています 騒ぎ立てる, 、Rails の移行をモデルにした PHP 移行システム。それはあなたが探しているものかもしれません。

他のヒント

私たちは bcwoord に似たものを使用して、5 つの異なるインストール (運用環境、ステージング環境、およびいくつかの開発環境) 間でデータベース スキーマの同期を維持し、バージョン管理でバックアップしています。これは非常にうまく機能します。少し詳しく説明します:


データベース構造を同期するには、update.php という 1 つのスクリプトと、1.sql、2.sql、3.sql などの番号が付けられた多数のファイルが必要です。このスクリプトは、データベースの現在のバージョン番号を保存するために 1 つの追加のテーブルを使用します。N.sql ファイルは、データベースのバージョン (N-1) からバージョン N に移行するために手動で作成されます。

これらは、テーブルの追加、列の追加、古い列形式から新しい列形式へのデータの移行、列の削除、ユーザー タイプなどの「マスター」データ行の挿入に使用できます。基本的に、何でも行うことができ、適切なデータ移行スクリプトを使用すれば、データが失われることはありません。

更新スクリプトは次のように動作します。

  • データベースに接続します。
  • 現在のデータベースのバックアップを作成します( 意思 間違ってください) [mysqldump]。
  • 簿記テーブル (_meta と呼ばれる) が存在しない場合は作成します。
  • _meta テーブルから現在のバージョンを読み取ります。見つからない場合は 0 とみなされます。
  • VERSION より大きい番号が付いたすべての .sql ファイルについて、順番に実行します。
  • いずれかのファイルでエラーが発生した場合:バックアップにロールバックする
  • それ以外の場合は、簿記テーブル内のバージョンを、実行された最も新しい .sql ファイルに更新します。

すべてがソース管理され、すべてのインストールには 1 回のスクリプト実行 (適切なデータベース パスワードを使用して update.php を呼び出すなど) で最新バージョンに更新するスクリプトが含まれています。SVN は、データベース更新スクリプトを自動的に呼び出すスクリプトを介してステージング環境と実稼働環境を更新します。そのため、コードの更新には必要なデータベースの更新が含まれます。

同じスクリプトを使用して、データベース全体を最初から再作成することもできます。データベースを削除して再作成し、データベースを完全に再設定するスクリプトを実行するだけです。スクリプトを使用して、自動テスト用に空のデータベースを作成することもできます。


このシステムのセットアップには数時間しかかかりませんでした。概念的にシンプルで、誰もがバージョン番号付けスキームを取得できます。また、変更を連絡したり手動で実行したりすることなく、データベース設計を前進させ進化させることができるという点で非常に貴重です。すべてのデータベース上で。

ただし、phpMyAdmin からクエリを貼り付ける場合は注意してください。 これらの生成されたクエリには通常、データベース名が含まれていますが、スクリプトが壊れてしまうため、これは絶対に避けてください。CREATE TABLE のようなもの mydb.newtable(...) システム上のデータベースの名前が mydb でない場合は失敗します。を含む .sql ファイルを禁止するプレコメント SVN フックを作成しました。 mydb これは、誰かが適切なチェックを行わずに phpMyAdmin からコピー/ペーストしたことを示す確実な兆候です。

私のチームはデータベースのすべての変更をスクリプト化し、アプリケーションの各リリースとともにそれらのスクリプトを SVN にコミットします。これにより、データを失うことなくデータベースを段階的に変更できます。

あるリリースから次のリリースに移行するには、一連の変更スクリプトを実行するだけで、データベースは最新の状態になり、すべてのデータが保持されます。最も簡単な方法ではないかもしれませんが、間違いなく効果的です。

ここでの問題は、開発者がソース管理に独自のローカル変更をスクリプト化してチームと共有することを容易にすることです。私は長年この問題に直面してきましたが、データベース プロフェッショナル向けの Visual Studio の機能に触発されました。同じ機能を備えたオープンソース ツールが必要な場合は、これを試してください。 http://dbsourcetools.codeplex.com/ 楽しんでください - ネイサン。

まだ解決策を探している場合:私たちはneXtep デザイナーというツールを提案しています。これは、データベース全体をバージョン管理下に置くことができるデータベース開発環境です。すべての変更を追跡できるバージョン管理されたリポジトリで作業します。

更新をリリースする必要がある場合、コンポーネントをコミットすると、製品によって以前のバージョンから SQL アップグレード スクリプトが自動的に生成されます。もちろん、この SQL は 2 つのバージョンから生成できます。

次に、多くのオプションがあります。これらのスクリプトを取得し、アプリ コードとともに SVN に配置すると、既存のメカニズムによってデプロイされるようになります。もう 1 つのオプションは、 neXtep の配信メカニズムを使用することです。スクリプトは「配信パッケージ」(SQL スクリプト + XML 記述子) と呼ばれるものでエクスポートされ、インストーラーはこのパッケージを理解して、構造の一貫性、依存関係のチェック、インストールされたバージョンの登録などを確保しながらターゲット サーバーに展開できます。

この製品は GPL であり、Eclipse に基づいているため、Linux、Mac、および Windows 上で実行できます。現時点では、Oracle、Mysql、Postgresql もサポートしています (DB2 のサポートは準備中です)。より詳細な情報が記載されている wiki を参照してください。http://www.nextep-softwares.com/wiki

スキーマをファイルにダンプし、ソース管理に追加します。次に、単純な diff で何が変更されたのかがわかります。

Scott Ambler は素晴らしい一連の記事を作成しています (また、 ) データベースのリファクタリングについて、基本的に TDD の原則と実践をスキーマの維持に適用する必要があるという考えに基づいています。データベースの一連の構造テストとシード データ単体テストを設定します。次に、何かを変更する前に、その変更を反映するようにテストを変更/作成します。

私たちはこれをしばらく続けてきましたが、効果があるようです。単体テスト スイートで基本的な列名とデータ型のチェックを生成するコードを作成しました。これらのテストはいつでも再実行して、SVN チェックアウト内のデータベースがアプリケーションが実際に実行しているライブ データベースと一致することを確認できます。

結局のところ、開発者はサンドボックス データベースを微調整し、SVN のスキーマ ファイルの更新を怠ることもあります。コードは、チェックインされていないデータベースの変更に依存します。この種のバグを特定するのは非常に難しい場合がありますが、テスト スイートはすぐに検出します。これは、大規模な継続的インテグレーション プランに組み込んでいる場合に特に便利です。

K.Scott Allen には、スキーマのバージョン管理に関するまともな記事が 1 つまたは 2 つあります。これは、ここでの他の回答で参照されている増分更新スクリプト/移行の概念を使用しています。見る http://odetocode.com/Blogs/scott/archive/2008/01/31/11710.aspx.

これはちょっとローテクで、もっと良い解決策があるかもしれませんが、データベースを作成するために実行できる SQL スクリプトにスキーマを保存することもできます。コマンドを実行してこのスクリプトを生成できると思いますが、残念ながらコマンドがわかりません。

次に、スクリプトを、その上で動作するコードとともにソース管理にコミットします。コードとともにスキーマを変更する必要がある場合は、変更されたスキーマを必要とするコードとともにスクリプトをチェックインできます。次に、スクリプトの差分はスキーマ変更の差分を示します。

このスクリプトを使用すると、DBUnit またはある種のビルド スクリプトと統合できるため、すでに自動化されているプロセスに適合できるようです。

C# を使用している場合は、Subsonic を参照してください。これは非常に便利な ORM ツールですが、スキームやデータを再作成するための SQL スクリプトも生成します。これらのスクリプトはソース管理に入れることができます。

http://subsonicproject.com/

Visual Studio で次のデータベース プロジェクト構造をいくつかのプロジェクトに使用しましたが、非常にうまく機能しました。

データベース

スクリプトの変更

0.PreDeploy.sql

1.SchemaChanges.sql

2.DataChanges.sql

3.権限.sql

スクリプトの作成

スプロック

機能

ビュー

次に、ビルド システムは、次の順序でスクリプトを実行することにより、データベースをあるバージョンから次のバージョンに更新します。

1.PreDeploy.sql

2.SchemaChanges.sql

「Create Scripts」フォルダーの内容

2.DataChanges.sql

3.権限.sql

各開発者は、コードを各ファイルの末尾に追加して、特定のバグ/機能の変更をチェックインします。メジャー バージョンが完了し、ソース管理で分岐すると、Change Scripts フォルダー内の .sql ファイルの内容が削除されます。

私たちは非常にシンプルですが効果的なソリューションを使用しています。

新規インストールの場合、リポジトリ内にすべての DB スキーマを保持する metadata.sql ファイルがあり、ビルド プロセスでこのファイルを使用してデータベースを生成します。

アップデートの場合は、ハードコードされたソフトウェアにアップデートを追加します。実際に問題が起きる前に問題を解決するのが好きではないため、私たちはハードコーディングしたままにしていますが、この種のことは今のところ問題であることが判明していません。

したがって、私たちのソフトウェアには次のようなものがあります。

RegisterUpgrade(1, 'ALTER TABLE XX ADD XY CHAR(1) NOT NULL;');

このコードは、データベースがバージョン 1 (自動的に作成されたテーブルに格納されている) かどうかを確認し、古い場合はコマンドを実行します。

リポジトリ内のmetadata.sqlを更新するには、このアップグレードをローカルで実行し、完全なデータベースのメタデータを抽出します。

時々起こる唯一のことは、metadata.sql のコミットを忘れることですが、ビルド プロセスでのテストが簡単で、起こり得る唯一のことは、次のコマンドを使用して新規インストールを行うことであるため、大きな問題ではありません。データベースが古いため、最初の使用時にアップグレードされました。

また、ダウングレードはサポートされていませんが、これは仕様であり、更新時に問題が発生した場合は、再試行する前に以前のバージョンを復元し、更新を修正しました。

ビルド バージョンにちなんだ名前のフォルダーを作成し、そこにアップグレード スクリプトとダウングレード スクリプトを置きます。たとえば、次のようなフォルダーが考えられます。1.0.0、1.0.1、1.0.2。それぞれに、バージョン間でデータベースをアップグレードまたはダウングレードできるスクリプトが含まれています。

1.0.2 を使用しているときに、クライアントまたは顧客からバージョン 1.0.1 の問題について電話がかかってきた場合、データベースをそのバージョンに戻すことは問題ありません。

データベースに、現在のバージョンのデータベースを入れる「スキーマ」というテーブルを作成します。そうすれば、データベースをアップグレードまたはダウングレードできるプログラムを作成するのは簡単です。

Joey が言ったように、Rails の世界にいるのであれば、Migrations を使用してください。:)

現在の PHP プロジェクトでは、rails 移行のアイデアを使用しており、ファイル タイトル「migration_XX.sql」を保持する移行ディレクトリがあります。XX は移行の番号です。現在、これらのファイルは更新時に手動で作成されていますが、その作成は簡単に変更できます。

次に、「Migration_watcher」と呼ばれるスクリプトがあります。これはプレアルファ版であるため、現在はすべてのページ読み込み時に実行され、新しいmigration_XX.sqlファイルがあるかどうかをチェックします。XXは現在の移行バージョンより大きいです。そうであれば、データベースに対して最大数まですべての migration_XX.sql ファイルが実行され、出来上がりです。スキーマの変更は自動化されます。

システムを元に戻す機能が必要な場合は、多くの調整が必要になりますが、それは簡単で、これまでのところ、私たちのかなり小規模なチームでは非常にうまく機能しています。

「スクリプト」側には Ant (クロスプラットフォーム) を使用し (実際には jdbc 経由であらゆる DB と通信できるため)、ソース リポジトリには Subversion を使用することをお勧めします。Ant を使用すると、変更を加える前にデータベースをローカル ファイルに「バックアップ」できます。1.ANT 2を介してファイルする既存のDBスキーマをバックアップします。ANT 3を介したバージョン制御からSubversionリポジトリへ。Ant経由で新しいSQL文をデータベースに送信します

Toad for MySQL には、2 つのデータベースを同期できるスキーマ比較と呼ばれる機能があります。これは私がこれまで使用した中で最高のツールです。

私見ですが、移行には大きな問題があります。

あるバージョンから別のバージョンへのアップグレードは正常に機能しますが、(私たちのように) 何百ものテーブルと長い変更履歴がある場合、特定のバージョンの新規インストールを実行すると、永遠に時間がかかる可能性があります。

ベースラインから現在のバージョンに至るまでの差分履歴全体を (数百の顧客データベースに対して) 実行すると、非常に長い時間がかかる可能性があります。

私はその方法が好きです いい データベースの移行を処理します。移行は基本的に PHP スクリプトを実装することです。 CDbMigration. CDbMigration を定義します up 移行ロジックを含むメソッド。を実装することも可能です。 down 移行の逆転をサポートするメソッド。あるいは、 safeUp または safeDown トランザクションのコンテキストで移行が確実に行われるようにするために使用できます。

Yii のコマンドライン ツール yiic 移行の作成と実行のサポートが含まれています。移行は、1 つずつまたはバッチで適用または元に戻すことができます。移行を作成すると、PHP クラスのコードが実装されます。 CDbMigration, 、タイムスタンプとユーザーが指定した移行名に基づいて一意に名前が付けられます。以前にデータベースに適用されたすべての移行は、移行テーブルに保存されます。

詳細については、を参照してください。 データベースの移行 マニュアルの記事。

db-deploy を試してみてください - 主に Java ツールですが、php でも動作します。

コマンドラインがあります mysql-diff データベース スキーマを比較するツール。スキーマは、ディスク上のライブ データベースまたは SQL スクリプトです。これは、ほとんどのスキーマ移行タスクに適しています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top