web-dev-qa-db-ja.com

データベース展開戦略(SQL Server)

毎日の展開を行い、データベーススクリプトをリリースに合わせて維持する方法を探しています。

現在、ソースをデプロイするためのかなり適切な方法があり、ユニットコードカバレッジ、継続的インテグレーション、およびロールバック手順があります。

問題は、データベーススクリプトをリリースに合わせて維持することです。誰もがテストデータベースでスクリプトを試し、ライブで実行しているようです。ORMマッピングが更新されると(つまり、変更がライブになります)、新しい列が取得されます。

最初の問題は、スクリプトをどこにも書き込む必要がないことです。通常、誰もがスクリプトをSubversionフォルダーに「入れよう」としますが、怠惰な人の中には、ライブでスクリプトを実行するだけで、ほとんどの場合、誰がスクリプトを実行したかを知りません。データベースに何を。

2番目の問題は、4つのテストデータベースがあり、それらは常にラインから外れており、それらを真にバックアップする唯一の方法は、ライブデータベースから復元することです。

私は、このようなプロセスは、開発者を妨げるのではなく、支援するために、シンプルでわかりやすく、使いやすいものである必要があると信じています。

私が探しているのは、開発者がデータベーススクリプトを記録して、リリース手順の一部として実行できるようにするためのテクニック/アイデアです。 開発者が従いたいと思うプロセス

ストーリー、ユースケース、またはリンクさえも役に立ちます。

52
cgreeno

この非常に問題のために、私は移行ツールを使用することを選択しました: Migratordotnet

(任意のツールでの)移行では、変更を実行して元に戻すために使用される単純なクラスがあります。次に例を示します。

[Migration(62)]
public class _62_add_date_created_column : Migration
{
    public void Up()
    {
       //add it nullable
       Database.AddColumn("Customers", new Column("DateCreated", DateTime) );

       //seed it with data
       Database.Execute("update Customers set DateCreated = getdate()");

       //add not-null constraint
       Database.AddNotNullConstraint("Customers", "DateCreated");
    }

    public void Down()
    {
       Database.RemoveColumn("Customers", "DateCreated");
    }
}

この例は、既存のデータがあるテーブルに新しいnull以外の列を追加するなど、揮発性の更新を処理する方法を示しています。これは簡単に自動化でき、バージョン間を簡単に上下できます。

これは私たちのビルドへの本当に価値のある追加であり、プロセスを合理化しました非常に

.NETのさまざまな移行フレームワークの比較をここに投稿しました: http://benscheirman.com/2008/06/net-database-migration-tool-roundup

32
Ben Scheirman

読む データベースのバージョン管理に関するK.Scott Allenの一連の投稿
彼が説明する手法に基づいて、制御された方法でデータベーススクリプトを適用するためのツールを構築しましたが、それはうまく機能します。
これは、データベースアップグレードスクリプトを保持するURLにコミットが行われたときに、各テストデータベースに変更がデプロイされた継続的インテグレーションプロセスの一部として使用できます。ベースラインスクリプトを用意することをお勧めします。スクリプトをアップグレードして、一連のスクリプトをいつでも実行して、データベースを現在のバージョンから必要な新しい状態に取得できるようにします。
ただし、これには開発者によるプロセスと規律が必要です(すべての変更は、新しいバージョンの基本インストールスクリプトとパッチスクリプトに組み込む必要があります)。

7
Hamish Smith

RedGateのSQLCompareを数年使用しています。

http://www.red-gate.com/products/index.htm

プロバージョンには、展開手順のセットアップに使用できるコマンドラインインターフェイスがあります。

6
Mike K.

K。Scott Allen によって記述されたデータベースバージョン管理の修正バージョンを使用します。 データベース公開ウィザード を使用して、元のベースラインスクリプトを作成します。次に、SQL SMOに基づくカスタムC#ツールを使用して、ストアドプロシージャ、ビュー、およびユーザー関数をダンプします。スキーマとデータの変更を含む変更スクリプトは、 Red Gate ツールによって生成されます。だから私たちは次のような構造になります

Database\
    ObjectScripts\ - contains stored procs, views and user funcs 1-per file
    \baseline.sql - database snapshot which includes tables and data
    \sc.01.00.0001.sql - incremental change scripts
    \sc.01.00.0002.sql
    \sc.01.00.0003.sql

カスタムツールは、必要に応じてデータベースを作成し、必要に応じてbaseline.sqlを適用し、必要に応じてSchemaChangesテーブルを追加し、SchemaChangesテーブルの内容に基づいて必要に応じて変更スクリプトを適用します。このプロセスは、cc.netを介してデプロイメントビルドを実行するたびに、nantビルドスクリプトの一部として発生します。

誰かがschemachangerアプリのソースコードが必要な場合は、codeplex/googleまたはどこにでもそれを投げることができます。

5
Todd Smith

ここに行く:

https://blog.codinghorror.com/get-your-database-under-version-control/

Odetocode.comWebサイトへの5つのリンクのリストまで少し下にスクロールします。素晴らしい5部構成のシリーズ。私はそれを出発点として使用して、アイデアを得て、チームに役立つプロセスを見つけます。

4
Clyde

データベーススキーマの同期を維持しようとしている場合は、 Red Gate SQL Comparison SDK を使用してみてください。作成スクリプト(newDb)に基づいて一時データベースを構築します-これは、データベースをどのように見せたいかです。 newDbを古いデータベース(oldDb)と比較します。その比較から変更セットを取得し、RedGateを使用して適用します。このアップグレードプロセスをテストに組み込むことができ、すべての開発者に、データベースの作成スクリプトが保持される場所が1つあることに同意してもらうことができます。これと同じ方法は、複数のバージョン間でデータベースをアップグレードし、各ステップ間でデータ移行スクリプトとプロセスを実行する場合に適しています(XMLドキュメントを使用して作成スクリプトとデータ移行スクリプトをマップします)

編集:Red Gateの手法では、Red Gateがアップグレードスクリプトを作成するため、スクリプトの作成のみに関心があり、アップグレードスクリプトには関心がありません。また、インデックス、ストアドプロシージャ、関数などを削除して作成することもできます。

4
Mike

MSBuildやNAntなどのビルドツールの使用を検討する必要があります。 CruiseControl.NET、NAnt、およびSourceGear Fortressの組み合わせを使用して、SQLオブジェクトを含むデプロイメントを処理します。 NAnt dbビルドタスクはsqlcmd.exeを呼び出して、Fortressにチェックインした後、開発環境とステージング環境のスクリプトを更新します。

2
Robert S.

Gusは手に負えないほど言及しました DB Ghost (上記)–私はそれを潜在的な解決策として2番目にしています。

私の会社がDBGhostをどのように使用しているかの概要:

  • 新しいDBのスキーマが初期開発中に合理的に解決された後、DB Ghostの「データとスキーマスクリプター」を使用してすべてのDBオブジェクト(および静的データ)のスクリプト(.sql)ファイルを作成し、チェックインします。これらのスクリプトファイルをソースコントロールに(ツールはオブジェクトを「ストアドプロシージャ」、「テーブル」などのフォルダに分割します)。この時点で、DBGHostの「Packager」ツールまたは「PackagerPlus」ツールのいずれかを使用してスタンドアロンの実行可能ファイルを作成し、これらのスクリプトから新しいDBを作成できます。
  • DBスキーマへのすべての変更は、特定のスクリプトファイルへのチェックインによってソースにチェックインされます。
  • いつでもパッケージャーを使用して実行可能ファイルを作成し、(a)新しいDBを作成するか、(b)既存のDBを更新することができます。特定のパス依存の変更(データの更新が必要な変更など)にはある程度のカスタマイズが必要ですが、更新前と更新後のスクリプトが実行されます。

「更新」プロセスには、クリーンな「ソース」DBの作成と、(更新前のカスタムスクリプトの後)ソースDBとターゲットDBのスキーマの比較が含まれます。 DB Ghostは、ターゲットDBを更新して一致させます

私たちは定期的に本番DBに変更を加えます(7つの異なる本番環境に14人の顧客がいます)が、必然的にDB Ghost更新実行可能ファイル(ビルドプロセス中に作成された)を使用して十分な数の変更を展開します。ソースにチェックインされなかった(またはリリースされている適切なブランチにチェックインされなかった)本番環境の変更はすべて失われます。これにより、全員が一貫して変更をチェックインする必要がありました。

要約する:

  • すべてのDB更新がDBGhost更新実行可能ファイルを使用して展開されるというポリシーを適用すると、暫定的に手動で展開されているかどうかに関係なく、開発者に変更を一貫してチェックインするように「強制」できます。
  • ビルドプロセスに1つまたは複数のステップを追加してDBGhost更新実行可能ファイルを作成すると、実際には、スクリプトからDBを作成できることを確認するためのテストが実行されます(つまり、DB Ghostは、作成時でも「ソース」DBを作成するため)更新実行可能パッケージ)および更新パッケージを実行するための1つまたは複数のステップを追加すると(前述の4つのテストDBのいずれかで)、テストDBをソースと一致させることができます。

このツール(実際には関連ツールのスイート)で「簡単に」展開できる変更にはいくつかの注意点と制限がありますが、それらはすべてかなりマイナーです(少なくとも私の会社にとって):

  • オブジェクトの名前変更は、カスタムスクリプトの1つで行う必要があります
  • DB全体が常に更新されるため(たとえば、単一のスキーマ内のオブジェクトを単独で更新することはできません)、メインアプリケーションDBで顧客固有のオブジェクトをサポートすることは困難です。
1
Kenny Evitt

Visual Studio for Database Professionals およびTFSを使用して、データベースの展開をバージョン管理および管理します。これにより、データベースをコードと同じように扱い(チェックアウト、チェックイン、ロック、バージョン履歴の表示、分岐、ビルド、デプロイ、テストなど)、必要に応じて同じソリューションファイルに含めることもできます。

当社の開発者は、ローカルデータベースで作業して、共有環境で互いの変更を踏まないようにすることができます。彼らがデータベースの変更をTFSにチェックするとき、統合された開発環境を構築、テスト、およびデプロイするための継続的インテグレーションがあります。リリースブランチには個別のビルドがあり、後続の環境ごとに異なるデプロイメントスクリプトを作成します。

後で、リリースでバグが発見された場合は、リリースブランチに移動して、コードとデータベースを同時に修正プログラムすることができます。

これは素晴らしい製品ですが、マイクロソフトのマーケティングの失敗により、早期に採用が妨げられました。もともとはチームシステムの別の製品でした。つまり、開発者版とデータベース版の機能を同時に使用するには、はるかに高価なTeamSuite版にステップアップする必要がありました。私たち(および他の多くの顧客)はこれについてマイクロソフトに悲しみを与えました、そして彼らが今年発表したことを非常に嬉しく思います DB Proは開発者版に組み込まれました そして開発者版のライセンスを持っている人なら誰でもすぐにインストールできますデータベース版。

1
Jerry Bullard

考えられる解決策の1つは、テストデータベースへのDML監査の実装を検討し、それらの監査ログをスクリプトにロールインして、最終テストとライブ展開を行うことです。 SQL Server 2008はDML監査を大幅に改善していますが、SQL Server2005でもトリガーを介してそれをサポートしています。

0
richardtallent

データベースのバージョン管理を自動化された方法で処理するための.NETベースのツールを作成しました。このツールを本番環境で使用して、データベースの更新(パッチを含む)の複数の環境へのロールアウトを処理し、スクリプトが実行された各データベースにログを保持し、すべてを自動化された方法で実行します。コマンドラインコンソールがあるため、このツールを使用するバッチスクリプトを作成できます。チェックしてください: https://github.com/bmontgomery/DatabaseVersioning

0

これらの投稿には、フォローアップしたいリンクがたくさんあります(数年前に「自分でロールした」システムで、類似点があるかどうかを確認する必要があります)。あなたが必要とするであろう、そして私がこれらのリンクで言及されることを望む一つのことは、規律です。誰かがいつでも何かを変更できる場合、自動化されたシステムがどのように機能するかはよくわかりません。 (あなたの質問は、これが実動システムで発生する可能性があることを意味しますが、明らかにそれは真実ではありません。)

データベース、特に本番データベースへの変更を管理するタスクに専念する1人の担当者(伝説の「データベース管理者」)を持つことは、非常に一般的なソリューションです。 X開発およびテストデータベース全体の一貫性を維持することに関して:それ/それらが多くのユーザーによって使用されている場合、もう一度、個人を変更の「クリアリングハウス」として機能させることが最善のサービスです。全員が独自のデータベースインスタンスを持っている場合は、それを整理する責任があり、更新されたベースラインデータベースが必要な場合は、中央の一貫性のあるデータベース「ソース」を持つことが重要になります。

興味深いかもしれない最近のStackOverflowの投稿は次のとおりです: how-to-refresh-a-test-instance-of-sql-server-with-production-data-without-using

0
Philip Kelley

この本 データベースのリファクタリング は、これらの問題の多くを概念レベルで扱っています。

ツールに関する限り、 DB Ghost はSQLServerでうまく機能することを私は知っています。 Visual Studioの Data Dude エディションは、最新のリリースで実際に改良されていると聞きましたが、経験はありません。

継続的インテグレーションスタイルのデータベース開発を実際に実行する限り、必要なデータベースコピーの数が多いため、リソースを大量に消費することになります。データベースが開発者のワークステーションに収まる場合は非常に実行可能ですが、データベースが大きすぎてグリッド全体に展開する必要がある場合は実用的ではありません。これを行うには、開発者[procsの変更だけでなく、DDLの変更を行う開発者]ごとにデータベースの1つのコピーと6つの一般的なコピーが必要です。一般的なコピーは次のとおりです。

  1. INT DEV->開発者は、統合テストのためにリファクタリングをINTDEVに「チェックイン」します。統合テストに合格すると、このデータベースはDEVにコピーされます。
  2. DEV->これはデータベースの「公式」開発コピーです。 INT DEVは、DEVのコピーで定期的に更新されます。新しいリファクタリングに取り組んでいる開発者は、DEVからデータベースの新しいコピーを取得します。
  3. INT QA-> QAチームを除いて、INTDEVと同じアイデア。ここで統合テストに合格すると、このデータベースはQAとDEV *にコピーされます。
  4. QA
  5. INT PROD->プロダクションを除いて、INTQAと同じアイデア。ここで統合テストに合格すると、このデータベースはPROD、QA *、およびDEV *にコピーされます。
  6. PROD

* DEV/QA/PROD行間でデータベースをコピーする場合は、特定の環境に関連するテストデータを更新するスクリプトも実行する必要があります(たとえば、QAチームがテストに使用するが本番環境には存在しないユーザーをQAに設定する)。

0
Gus

Red Gateには、ビルドの自動化を実現する方法を説明するペーパーがあります。 http://downloads.red-gate.com/HelpPDF/ContinuousIntegrationForDatabasesUsingRedGateSQLTools.pdf

これは SQLソース管理 を中心に構築されており、SSMSおよび既存のソース管理システムと統合されています。

0
David Atkinson

これは、以前の雇用主が使用していたシンプルで低コストのアプローチの実際の例です(そして、基本的な最初のステップとして現在の雇用主に印象づけようとしています)。

'DB_VERSION'などのテーブルを追加します。すべてのアップグレードスクリプトで、そのテーブルに行を追加します。この行には、アップグレードを説明するのに適した列をいくつでも含めることができますが、少なくとも{VERSION、EXECUTION_DATE、DESCRIPTION、EXECUTION_USER}をお勧めします。これで、何が起こっているのかについて具体的な記録ができました。誰かが独自の無許可のスクリプトを実行する場合でも、上記の回答のアドバイスに従う必要がありますが、これは既存のバージョン管理を劇的に改善する簡単な方法です(つまり、なし)。

ここで、データベースのv2.1からv2.2へのアップグレードスクリプトがあり、孤独な異端者が実際にデータベースで実行したことを確認したい場合は、VERSION = 'v2.2'である行を検索するだけです。結果が得られた場合は、このアップグレードスクリプトを実行しないでください。必要に応じて、コンソールユーティリティアプリに組み込むことができます。

0
Lisa