開発、テスト、本番環境でデータベースをどのように管理しますか?


171

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

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

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

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

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

問題がスキーマだけだった場合は、もっと簡単な問題ですが、データベースには、セキュリティテーブルや権限テーブルのメタデータなど、開発中にも更新される「ベース」データがあります。

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


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


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

*.sql特定のディレクトリにあるスクリプトの名前をデータベースのテーブルと照合し、そこにないものをファイル名の最初の部分を形成する整数に基づいて順番に実行するPythonスクリプトを作成します。それがかなりシンプルなソリューションである場合、私はそれがそうであると思うので、私はそれをここに投稿します。


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



「特定のディレクトリにある* .sqlスクリプトの名前をデータベースのテーブルと照合し、そこにないものを最初の部分を形成する整数に基づいて順番に実行するPythonスクリプトを作成しますファイル名。それがかなりシンプルな解決策である場合、私はそうなると思うので、ここに投稿します。」フライウェイを実装しているようですね。
masterxilo

回答:


53

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

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

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


28

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

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


13

Ruby on Railsがこれをどのように行うかを見てください。

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

テストデータベースは、ユニットテストの前に常に完全にワイプされ、ファイルからの固定データが入力されます。


10

データベースのリファクタリング:進化するデータベースの設計』では、データベースの管理方法についていくつかのアイデアが得られるかもしれません。短いバージョンはhttp://martinfowler.com/articles/evodb.htmlでも読むことができます

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


5
  • 次のようにデータベースに名前を付けます- dev_<<db>> , tst_<<db>> , stg_<<db>> , prd_<<db>>(明らかに、db名をハードコードすべきではありません
  • したがって、同じ物理サーバーに異なるタイプのデータベースをデプロイすることもできます(推奨しませんが、リソースが不足している場合は...)
  • それらの間でデータを自動的に移動できることを確認してください
  • db作成スクリプトを母集団から分離する= dbを最初から再作成し、(古いdbバージョンまたは外部データソースから)作成することは常に可能です
  • コードでハードコード接続文字列を使用しないでください(構成ファイルでさえも使用しない)-動的に入力する構成ファイル接続文字列テンプレートで使用します。再コンパイルが必要なapplication_layerの各再構成は不良です
  • データベースのバージョン管理とdbオブジェクトのバージョン管理を使用する-余裕がある場合は、既成の製品を使用し、自分で開発しない場合
  • 各DDL変更を追跡し、いくつかの履歴テーブルに保存します(ここの例
  • 毎日のバックアップ!バックアップから失われたものを復元できる速度をテストします(自動復元スクリプトを使用します)
  • DEVデータベースとPRODでもまったく同じ作成スクリプトがあり、データに問題が発生するため、開発者がprodの正確なコピーを作成してそれを操作できるようにします(これについてはマイナスが表示されますが、マインドセットとビジネスプロセスは、たわごとがファンに当たったときのコストがはるかに低くなるので、コーダーに合法的に下付き文字を添えさせるが、これを確実にする

最後のポイントは確かに気分です。必要な場合は、プロジェクトの定義が壊れていることを示しています。開発は生産の前にリードする必要があります。生産データが副作用を誘発する場合、より大きな問題を示します。本番データをクリーンアップします。また、データ保護担当者との最後のステップを明確にします。ライブデータを開発システム上に置く必要があるという理由がある場合は、これが法的に適用可能かどうかを確認してください。また、本番データの正確なコピーは、開発と統合の速度を大幅に低下させます。そのような贅沢を買う余裕がないなら、より費用のかからないプロセスを考えてください。
hakre

問題は、開発中に、制御フローの隅々のケースや、本番環境で発生するデータ品質の変動を想定することさえ不可能であるということです。あなたがそのような大企業にいる場合、何らかのデータスクランブルやマスキングソリューションよりも法的な問題を抱えているため、実装が必要であり、複雑さがさらに増しますが、バグの原因となったデータ品質の側面を維持する必要があります。とにかくそもそも...
ヨルダンゲオルギエフ

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個のデルタスクリプトがあることがわかりました。ARGH!

最近では、1つのデルタスクリプトを保守し、SVNでバージョン管理できるようにしています。つまり、リリースごとにスクリプトを上書きしています。また、ブランチでスキーマを変更することは避けます。

それで、私もこれに満足していません。Railsからのマイグレーションの概念が本当に好きです。LiquiBaseにとても魅了されました。増分データベースリファクタリングの概念をサポートしています。それは一見の価値があり、私はすぐにそれを詳細に見ていきます。誰もがそれを経験していますか?あなたの結果を知りたいと思います。


4

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


3

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

開発者はプライベートDBを備えたVMで開発します。

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

テストはさまざまなマシンで実行されます(実際にはサーバーでホストされているVM内で)[間もなくHudson CIサーバーで実行されます]

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

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

本番環境はインストーラーとしてお客様に導入されます。

私達がすること:

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

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

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

(Juhaは、現在のDBバージョンを記録するテーブルを作成するというRailのアイデアは良いものであり、アップデートのインストールを簡単にする必要があると述べました。)

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


3

他のポスターに同意していると思います。開発者は変更をスクリプト化する必要があります。

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

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

それをCIサーバーにフックする方法はわかりません。おそらく、CIサーバーは既知のビルドスナップショットをオンにする必要があります。ビルドスナップショットは毎晩戻り、それ以降のすべての変更を適用します。それがおそらく最善の方法です。それ以外の場合、移行スクリプトが壊れると、その夜のビルドだけでなく、それ以降のすべてのビルドも壊れます。


1

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


1

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



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スキーマエクスポートまたはLinqToSql CreateDatabaseなどを使用して)。次に、作成した_devおよび_next DBを使用してmigrationscriptgeneratorを実行します。移行するためのSQL更新スクリプト。


0

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

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

  1. すべてのdbスキームに対してスキームDDLSを取得
  2. それをバージョン制御下に置く

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

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