DBスキーマの変更を追跡するメカニズム[終了]


135

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

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

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

回答:


56

Railsの世界には、データベース固有のSQLではなく、Rubyでデータベースに変更を加えるスクリプトであるマイグレーションの概念があります。Ruby移行コードは、現在のデータベースに固有のDDLに変換されます。これにより、データベースプラットフォームの切り替えが非常に簡単になります。

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

Railsの移行に関するこのOracleガイドでは、移行について十分に説明しています。

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


1
ラッキーFTW-私たちはそれを自分のdbシステムに適合させ、それに非常に満足しています。
Piskvorは、

現在githubにあります:github.com/ruckus/ruckusing-migrations

50

私たちはbcwoordに似たものを使用して、5つの異なるインストール(本番、ステージング、およびいくつかの開発インストール)間でデータベーススキーマを同期させ、バージョン管理でバックアップしました。少し詳しく説明します。


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

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

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

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

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

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


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

phpMyAdminからクエリを貼り付ける場合は注意してください。通常、これらの生成されたクエリにはデータベース名が含まれていますが、スクリプトが壊れるので、絶対に必要ありません。CREATE TABLEのようなものmydbnewtable(...)システム上のデータベースがmydbと呼ばれていない場合、失敗します。mydb文字列を含む.sqlファイルを許可しないコメント前のSVNフックを作成しました。これは、誰かが適切なチェックなしにphpMyAdminからコピー/貼り付けしたことを示す確かなサインです。


衝突をどのように処理しましたか?複数の開発者がDB内の同じ要素を変更した場合、たとえばストアドプロシージャ?これは、同じブランチで同時に作業している場合、または2つの開発ライン(2つのブランチ)を使用している場合に発生する可能性があります
Asaf Mesika

衝突は非常にまれでした。実際に起こった唯一のことは、2人が同じN.sqlファイルを作成しようとすることです。もちろん、最初の方が勝ち、2番目の方が次に大きい番号に名前を変更して再試行する必要があります。ただし、ブランチにはデータベースのバージョン管理がありませんでした。
rix0rrr 2010年

12

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

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


1
すべての変更をどのようにスクリプト化しますか?
スミス

10

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


10

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

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

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

製品はGPLで、Eclipseに基づいているため、Linux、Mac、Windowsで動作します。現在、Oracle、Mysql、Postgresqlもサポートしています(DB2のサポートは進んでいます)。より詳細な情報を見つけることができるウィキを見てください:http : //www.nextep-softwares.com/wiki


面白いですね。コマンドラインインターフェイスも備えていますか、それとも計画されていますか?
Piskvorが

8

スコット・アンブラーは記事の偉大なシリーズを生成し(と共著の本)あなたは、本質的に、あなたのスキーマを維持するためにTDDの原則と慣行を適用すべきであるという考えで、データベースリファクタリングに。データベースの一連の構造およびシードデータユニットテストを設定します。次に、何かを変更する前に、その変更を反映するようにテストを変更または記述します。

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

結局のところ、開発者はサンドボックスデータベースを微調整し、SVNのスキーマファイルの更新を怠ることもあります。次に、コードはチェックインされていないデータベースの変更に依存します。この種のバグは突き止めるのが非常に難しい場合がありますが、テストスイートはすぐにそれを認識します。これは、大規模な継続的統合計画に組み込む場合に特に便利です。


7

スキーマをファイルにダンプし、ソース管理に追加します。次に、単純なdiffが変更内容を示します。


1
ダンプはmysqldumpのようにSQLである必要があり、Oracleのダンプはバイナリです。
Osama Al-Maadeed 2008年

7
スキーマの比較には、より根本的な問題もあります。列のドロップ+追加と列の名前変更をどのように区別しますか?答えは簡単です。できません。これが、実際のスキーマ変更操作を記録する必要がある理由です。
psp

diffは、1つの列がなくなっているのに、他の列が(同じ名前でない限り)表示されていることを示し、ほとんどの場合それで十分です。もちろん、すべてのスキーマ変更のスクリプトを作成するのは良い方法です。Drupalでは、これはたとえば特別なフックによって処理されます。
デッドプログラマー2010


5

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

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

このスクリプトを使用すると、DBUnitまたはなんらかのビルドスクリプトと統合できるため、すでに自動化されているプロセスに適合する可能性があります。


ええ、それは私たちが現在実施しているもののほとんどです。残念ながら、既存のデータベースを変更する簡単な方法はありません。mysqldumpによって生成されたSQLスクリプトは、最初からテーブルを作成している(または存在する場合はテーブルを上書きしている)ことを前提としています。データベースに一連のALTER TABLEステートメントを適用する必要があるため、もう少しハイテクなものが必要です。これを適切に行うには、データベースの現在の状態を認識する必要があります。
pix0r 2008

5

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

http://subsonicproject.com/


この時点でデッドURLのようです。
Mark Schultheiss、2013

5

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

データベース

変更スクリプト

0.PreDeploy.sql

1.SchemaChanges.sql

2.DataChanges.sql

3.Permissions.sql

スクリプトを作成する

Sprocs

関数

ビュー

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

1.PreDeploy.sql

2.SchemaChanges.sql

スクリプト作成フォルダの内容

2.DataChanges.sql

3.Permissions.sql

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


5

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

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

アップデートについては、ハードコードされたソフトウェアにアップデートを追加します。本当に問題になる前に問題を解決するのは好きではないため、ハードコーディングされた状態を維持します。この種の問題は、今のところ問題であるとは証明されていません。

私たちのソフトウェアには次のようなものがあります:

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

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

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

たまに起こる唯一のことは、metadata.sqlのコミットを忘れることですが、これは大きな問題ではありません。ビルドプロセスで簡単にテストできることと、起こり得る唯一のことは、古くなったデータベースと最初の使用時にそれをアップグレードしました。

また、ダウングレードもサポートしていませんが、これは仕様によるもので、更新で何かが壊れた場合は、以前のバージョンを復元し、更新を修正してから再試行します。


4

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

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

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

Joeyが言ったように、Railsの世界にいる場合は、マイグレーションを使用してください。:)


3

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

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

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


3

"scripting"側にはAnt(クロスプラットフォーム)(jdbcを介して実際にあらゆるdbと通信できるため)およびソースリポジトリにはSubversionを使用することをお勧めします。Antは、変更を加える前に、dbをローカルファイルに「バックアップ」するように指示します。1. Antを介して既存のdbスキーマをファイルにバックアップ2. Antを介してSubversionリポジトリにバージョン管理3. Antを介して新しいSQLステートメントをdbに送信


3

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


3

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

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

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



2

私見の移行には大きな問題があります:

あるバージョンから別のバージョンへのアップグレードは問題なく機能しますが、特定のバージョンのフレッシュインストールを行うには、数百のテーブルと長い変更履歴(私たちのように)がある場合、時間がかかることがあります。

ベースラインから現在のバージョン(数百の顧客データベース)までのデルタの全履歴の実行には、非常に長い時間がかかる場合があります。


0

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.