177

開発サーバー、テスト サーバー、および運用サーバーの間でデータベース スキーマとデータを管理する方法の良い例を見つけるのに苦労しました。

これが私たちのセットアップです。各開発者は、アプリと MySQL データベースを実行する仮想マシンを持っています。彼らがやりたいことを何でもするための個人的なサンドボックスです。現在、開発者は SQL スキーマを変更し、SVN にコミットするテキスト ファイルにデータベースをダンプします。

コミットされた最新のコードを常に実行する継続的インテグレーション開発サーバーをデプロイしたいと考えています。ここでこれを行うと、ビルドごとに SVN からデータベースがリロードされます。

「リリース候補」を実行するテスト (仮想) サーバーがあります。現在、テスト サーバーへのデプロイは非常に手作業のプロセスであり、通常は SVN から最新の SQL を読み込んで微調整する必要があります。また、テスト サーバー上のデータには一貫性がありません。最終的には、最後にコミットした開発者がサンドボックス サーバーに持っていたテスト データがそのまま残ります。

すべてが崩壊するのは、本番環境へのデプロイです。ライブ データをテスト データで上書きすることはできないため、すべてのスキーマ変更を手動で再作成する必要があります。データを操作するために多数のスキーマ変更または変換スクリプトがあった場合、これは非常に複雑になる可能性があります。

問題が単なるスキーマである場合は、より簡単な問題になりますが、データベースには、セキュリティやアクセス許可テーブルのメタデータなど、開発中にも更新される「ベース」データがあります。

これが、継続的インテグレーションとワンステップ ビルドに移行する際の最大の障壁です。どのよう解決しますか?


フォローアップの質問: データベースのバージョンを追跡して、特定のデータベース インスタンスをアップグレードするために実行するスクリプトを知るにはどうすればよいですか? Lance のようなバージョン テーブルは、標準的な手順の下に記載されていますか?


タランティーノを参考にしていただきありがとうございます。私は .NET 環境ではありませんが、DataBaseChangeMangement wiki ページが非常に役立つことがわかりました。特にこのPowerpoint プレゼンテーション (.ppt)

*.sql特定のディレクトリ内のスクリプトの名前をデータベース内のテーブルと照合してチェックし、ファイル名の最初の部分を形成する整数に基づいて、そこにないスクリプトを順番に実行する Python スクリプトを作成します。それが非常に単純な解決策であると思われる場合は、ここに投稿します。


このための作業スクリプトがあります。DB が存在しない場合は DB の初期化を処理し、必要に応じてアップグレード スクリプトを実行します。既存のデータベースを消去し、ファイルからテスト データをインポートするためのスイッチもあります。200行くらいなので載せません(興味があればペーストビンに載せるかもしれませんが)。

4

14 に答える 14

55

いくつかの良いオプションがあります。「バックアップを復元する」戦略は使用しません。

  1. すべてのスキーマ変更のスクリプトを作成し、CI サーバーにそれらのスクリプトをデータベースで実行させます。現在のデータベース バージョンを追跡するためのバージョン テーブルを用意し、新しいバージョンの場合にのみスクリプトを実行します。

  2. 移行ソリューションを使用します。これらのソリューションは言語によって異なりますが、.NET には Migrator.NET を使用します。これにより、データベースのバージョンを管理し、バージョン間を上下に移動できます。スキーマは C# コードで指定されます。

于 2008-08-08T21:01:09.490 に答える
28

開発者は、単にデータベース全体をソース管理にダンプするだけでなく、作業するバグ/機能ごとに変更スクリプト (スキーマとデータの変更) を作成する必要があります。これらのスクリプトは、現在の本番データベースを開発中の新しいバージョンにアップグレードします。

ビルド プロセスでは、運用データベースのコピーを適切な環境に復元し、その上でソース管理からすべてのスクリプトを実行できます。これにより、データベースが現在のバージョンに更新されます。これを毎日行って、すべてのスクリプトが正しく実行されるようにします。

于 2008-08-08T21:03:32.933 に答える
14

Ruby on Rails がこれを行う方法を見てみましょう。

まず、いわゆる移行ファイルがあります。これは、基本的にデータベース スキーマとデータをバージョン N からバージョン N+1 に変換します (または、バージョン N+1 から N にダウングレードする場合)。データベースには、現在のバージョンを示すテーブルがあります。

テスト データベースは、単体テストの前に常に消去され、ファイルから固定データが取り込まれます。

于 2008-08-17T09:38:38.570 に答える
10

Refactoring Databases: Evolutionary Database Designという本は、データベースの管理方法に関するアイデアを提供してくれるかもしれません。http://martinfowler.com/articles/evodb.htmlでも短いバージョンを読むことができます。

ある PHP+MySQL プロジェクトでは、データベースのリビジョン番号をデータベースに保存しました。プログラムがデータベースに接続すると、最初にリビジョンがチェックされます。プログラムに別のリビジョンが必要な場合は、データベースをアップグレードするためのページが開きます。各アップグレードは PHP コードで指定され、データベース スキーマが変更され、既存のデータがすべて移行されます。

于 2009-02-12T14:41:04.710 に答える
5
  • 次のようにデータベースに名前を付けます - dev_<<db>> , tst_<<db>> , stg_<<db>> , prd_<<db>>(明らかに、データベース名をハードコードするべきではありません
  • したがって、異なるタイプの db を同じ物理サーバーに展開することもできます (お勧めしませんが、必要になる場合があります... リソースが逼迫している場合)
  • それらの間でデータを自動的に移動できることを確認してください
  • db 作成スクリプトを人口から分離する = db を最初から再作成し、(古い db バージョンまたは外部データソースから) いつでも再作成できる必要があります。
  • コードでハードコード接続文字列を使用しないでください (構成ファイルでなくても) - 動的に入力する構成ファイル接続文字列テンプレートで使用します。再コンパイルが必要な application_layer の各再構成は BAD です。
  • データベースのバージョン管理と db オブジェクトのバージョン管理を使用してください - 余裕がある場合は既製の製品を使用し、そうでない場合は自分で何かを開発します
  • 各 DDL 変更を追跡し、履歴テーブルに保存します (例はこちら) 。
  • 毎日のバックアップ!バックアップから失われたものをどれだけ速く復元できるかをテストします (自動復元スクリプトを使用します)
  • DEVデータベースとPRODでさえ、データに問題が発生するまったく同じ作成スクリプトを持っているため、開発者がprodの正確なコピーを作成してそれで遊ぶことができるようにします(これについてマイナスを受け取ることはわかっていますが、マインドセットとビジネスプロセスは、たわごとがファンを襲ったときのコストを大幅に削減します.
于 2009-04-22T06:38:02.427 に答える
5

また、 SQL Compareなどのツールを使用して、さまざまなバージョンのデータベースの違いをスクリプト化することもできます。これにより、バージョン間ですばやく移行できます。

于 2009-01-16T08:09:36.773 に答える
4

これは、私がいつも不満に思っていることです。つまり、この問題に対する私たちの解決策です。数年間、リリースごとに個別の変更スクリプトを維持してきました。このスクリプトには、最後の製品リリースからのデルタが含まれます。アプリケーションがリリースされるたびに、バージョン番号が増加し、次のようになります。

  • dbChanges_1.sql
  • dbChanges_2.sql
  • ...
  • dbChanges_n.sql

これは、新しい開発用のトランク/メインラインと、バグ修正や短期的な拡張などのためのメンテナンス ブランチの 2 つの開発ラインの維持を開始するまでは十分に機能していました。必然的に、ブランチのスキーマを変更する必要が生じました。この時点で、すでにトランクに dbChanges_n+1.sql があったため、最終的に次のようなスキームになりました。

  • dbChanges_n.1.sql
  • dbChanges_n.2.sql
  • ...
  • dbChanges_n.3.sql

繰り返しになりますが、これは十分に機能しましたが、ある日調べてみると、メインラインに 42 個、ブランチに 10 個のデルタ スクリプトがありました。アー!

最近では、単純に 1 つのデルタ スクリプトを維持し、それを SVN にバージョン管理させています。つまり、リリースごとにスクリプトを上書きしています。また、ブランチでスキーマを変更することをためらいます。

ですから、これでも満足できません。Rails からの移行のコンセプトがとても気に入っています。私はLiquiBaseにすっかり魅了されました。増分データベース リファクタリングの概念をサポートします。一見の価値があり、すぐに詳しく見ていきます。誰でも経験がありますか?私はあなたの結果について非常に興味があります。

于 2008-08-21T02:58:16.080 に答える
3

OPと非常によく似たセットアップがあります。

開発者は、プライベート DB を使用して VM で開発します。

[開発者はまもなくプライベート ブランチにコミットします]

テストはさまざまなマシンで実行されます (実際には、サーバーでホストされている VM 内にあります) [すぐに Hudson CI サーバーによって実行されます]

参照ダンプを db にロードしてテストします。開発者スキーマ パッチを適用してから、開発者データ パッチを適用します。

次に、単体テストとシステム テストを実行します。

製品は、インストーラーとしてお客様にデプロイされます。

私達がすること:

サンドボックス DB のスキーマ ダンプを取得します。次に、SQL データ ダンプ。それを前のベースラインと比較します。そのデルタのペアは、n-1 を n にアップグレードします。

ダンプとデルタを構成します。

したがって、バージョン N CLEAN をインストールするには、ダンプを空のデータベースに実行します。パッチを適用するには、介在するパッチを適用します。

(Juha は、現在の DB バージョンを記録するテーブルを持つという Rail のアイデアは優れたものであり、更新のインストールの負担を軽減するはずだと述べました。)

デルタとダンプは、ベータ テストの前に確認する必要があります。開発者が自分でテスト アカウントを DB に挿入するのを見たので、これを回避する方法はわかりません。

于 2008-09-02T23:30:03.217 に答える
3

残念ながら、私は他の投稿者と同意見です。開発者は、変更をスクリプト化する必要があります。

多くの場合、単純な ALTER TABLE は機能しません。既存のデータも変更する必要があります。開発者は、どの移行が必要かを確認し、それらが正しくスクリプト化されていることを確認する必要があります (もちろん、移行のある時点でこれを注意深くテストする必要があります)。リリースサイクル)。

さらに、感覚があれば、必要に応じて元に戻せるように、開発者に変更のロールバックのスクリプトを作成してもらうこともできます。これもテストして、ロールバックがエラーなしで実行されるだけでなく、DB が以前と同じ状態のままであることを確認する必要があります (これは常に可能または望ましいとは限りませんが、ほとんどの場合は適切なルールです)。 .

それをCIサーバーにどのようにフックするかはわかりません。おそらく、CI サーバーには既知のビルド スナップショットが必要です。これは毎晩元に戻り、それ以降のすべての変更を適用します。そうしないと、移行スクリプトが壊れて、その夜のビルドだけでなく、その後のビルドもすべて壊れてしまいます。

于 2009-01-16T07:07:11.780 に答える
1

コマンドラインmysql-diffを使用しています。これは、2つのデータベーススキーマ(ライブDBまたはスクリプトから)の違いをALTERスクリプトとして出力します。mysql-diffはアプリケーションの起動時に実行され、スキーマが変更された場合は開発者に報告します。したがって、開発者は手動でALTERを作成する必要はなく、スキーマの更新は半自動で行われます。

于 2009-11-04T19:55:32.500 に答える
1

dbdeployを確認してください。Java および .net ツールが既に利用可能です。SQL ファイル レイアウトとスキーマ バージョン テーブルの標準に従って、Python バージョンを記述できます。

于 2008-08-22T12:53:34.037 に答える
1

.NET 環境にいる場合、解決策はTarantino (アーカイブ済み)です。このすべて (インストールする SQL スクリプトを含む) を NANT ビルドで処理します。

于 2008-08-13T20:36:45.670 に答える
0

( Open DBDiffにフックすることによって) データベース スキーマを比較し、移行スクリプトを提案するツールを作成しました。データを削除または変更する変更を行うと、エラーがスローされますが、スクリプトに提案が表示されます (たとえば、新しいスキーマで列が見つからない場合、列の名前が変更されているかどうかを確認し、xx - 生成されたものを作成します) rename ステートメントを含む script.sql.suggestion)。

http://code.google.com/p/migrationscriptgenerator/ SQL Server のみ 残念ながら :( これもかなりアルファ版ですが、摩擦が非常に少ない (特に Tarantino またはhttp://code.googleと組み合わせる場合) .com/p/simplescriptrunner/ )

私がこれを使用する方法は、.sln に SQL スクリプト プロジェクトを作成することです。また、変更を加える db_next データベースがローカルにあります (Management Studio またはNHibernate Schema ExportまたはLinqToSql CreateDatabaseなどを使用)。次に、作成する _dev および _next DB で migrationscriptgenerator を実行します。移行のための SQL 更新スクリプト。

于 2009-02-12T14:17:41.943 に答える
0

Oracle データベースの場合、 oracle-ddl2svnツールを使用します。

このツールは次のプロセスを自動化します

  1. すべての db スキームに対してスキーム ddls を取得します
  2. バージョン管理下に置く

手動で解決されたインスタンス間の変更

于 2011-03-12T14:10:41.743 に答える