SOコミュニティウィキでは、データベースオブジェクトをバージョン管理する必要があるかどうかについて、いくつかの議論がありました。しかし、のベストプラクティスについては、あまり議論していませんデータベースオブジェクトのビルド自動化プロセスを作成します。
特に、開発者とDBAは、データベース展開への自動化アプローチのメリットとリスクを評価するときに、異なる目標、アプローチ、および懸念を抱くことが多いため、これは私のチームにとって議論の的となっています。
SOコミュニティから、現実の世界でどのような実践が効果的だったかについて、いくつかのアイデアを聞きたいと思います。
どのプラクティスが本当に最良であるかはやや主観的であると私は理解していますが、私は多くの人々にとってどのような仕事が役立つかについての良い対話を考えています。
これは、このトピックの懸念事項に関する私のティーザーの質問の一部です。これらは完全なリストではなく、人々が私が探しているものを理解するための出発点です。
可能な場合はSQLをソースコードとして扱います
標準に準拠したSQLで記述できる場合、通常はソース管理のファイルに入ります。ファイルは、SP、テーブルCREATEステートメントなど、できるだけ多くを定義します。
ソース管理でテストするためのダミーデータも含めます。
その後、MySQL、Oracle、MSSQLなどのプロジェクト全体を構築できるように、すべてのSQLクエリを抽象化します。
ビルドとテストの自動化では、これらのビルドスクリプトをアプリのソースと同じくらい重要として使用し、整合性からトリガー、手順、ロギングまですべてをテストします。
TeamCityを介した継続的な統合を使用しています。ソース管理にチェックインするたびに、データベースとすべてのテストデータが最初から再構築され、次にコードが再構築され、コードに対してユニットテストが実行されます。 CodeSmithなどのコード生成ツールを使用している場合は、それをビルドプロセスに配置して、各ビルドでデータアクセスレイヤーを新しく生成し、すべてのレイヤーが「一致」し、エラーが発生しないようにすることができます。 SPパラメータが一致していないか、列がありません。
各ビルドには、ソース管理の$ project\SQL \ディレクトリに保存されたSQLスクリプトの独自のコレクションがあり、数値のプレフィックスが割り当てられ、順番に実行されます。このようにして、すべてのビルドで展開手順を実践しています。
ルックアップテーブルによっては、ほとんどのルックアップ値もスクリプトに格納され、構成データが、たとえば「reason_codes」や「country_codes」に期待されるものであることを確認するために実行されます。このように、ツールを使用して本番環境でルックアップ値を変更する代わりに、開発でルックアップデータを変更してテストし、QAと本番環境を介して「昇格」させることができます。
また、本番環境へのビルドが不安定になった場合に備えて、データベースの変更を取り消す一連の「ロールバック」スクリプトを作成します。ロールバックスクリプトを実行してテストし、その後、配置スクリプトの実行後に、ビルドのユニットテストを1つ下のバージョンで再実行できます。
+1 forLiquibase: LiquiBase は、オープンソース(LGPL)であり、データベースを追跡、管理、適用するためのデータベースに依存しないライブラリです変更。シンプルな前提に基づいて構築されています。すべてのデータベースの変更(構造とデータ)は、XMLベースの記述的な方法で保存され、ソース管理にチェックインされます。良い点は、DMLの変更が差分だけでなく意味的に保存されるため、変更の目的を追跡できることです。
[〜#〜] git [〜#〜] と組み合わせると、より良い対話が可能になります。それを試すためにdev-prod環境を構成します。
また、スクリプトからプロダクションコードをビルドするためにMaven、Antビルドシステムを使用することもできます。
マイナス点は、LiquiBaseが広範なSQL IDEに統合されておらず、基本的な操作を自分で行う必要があることです。
これに加えて、DBテストに DBUnit を使用できます-このツールにより、データ生成スクリプトを使用して本番環境をテストできますクリーンアップを伴う環境。
私見では:
請求書作成データベースでのコード変更、マージ、リライトに関する前述のすべての問題に直面しました。このトピックは、それらすべてを発見するのに最適です。
私は基本的に van によって与えられるすべての答えに同意します。より深い洞察として、私のデータベース管理のベースラインは K。スコットアレンシリーズ です(必読です、私見です。そして ジェフの意見 もそうです)。
Create.sql
。これには、staticデータ挿入(リスト...)を含めることができます。Create.sql
:Create.cmd
を起動します。その目的は主に、前提条件(ツール、環境変数...)をチェックし、SQLスクリプトにパラメーターを送信することです。パフォーマンスの問題のために、CSVファイルから静的データをbulk-loadすることもできます。Create.cmd
ファイルに渡されます。IMHO、dynamicデータのロードには、環境に応じて別の手順が必要です。開発者は、テスト、ジャンク、またはまったくデータなしでデータベースをロードする必要がありますが、もう一方の端では、プロダクションマネージャーはプロダクションデータをロードする必要があります。 (たとえば、単体テストを容易にするために)ソース管理にもテストデータを格納することを検討します。
データベースの最初のバージョンが本番環境に配置されると、スクリプト(主に開発者向け)をビルドするだけでなく、(同じ原則に基づいて)アップグレードスクリプトも必要になります。
Upgrade.sql
ファイル(他のファイルを呼び出すことができる)を作成します。このスクリプトはN-1
という名前のフォルダーに保存します。Upgrade.cmd
があります。単純なSELECTステートメントを使用してデータベースの現在のバージョン(CV)を取得し、CV
フォルダーに保存されているUpgrade.sql
スクリプトを起動して、フォルダーが見つからなくなるまでループできます。このようにして、たとえばN-3からNに自動的にアップグレードできます。これに関する問題は次のとおりです。
どのようなデータベースオブジェクトをソース管理下に置きたいですか?ええと、私はできる限り多く言いますが、それ以上は言いません;-)パスワードを使用してユーザーを作成する場合は、デフォルトのパスワード(ログイン/ログイン、単体テストの目的で実用的)を取得し、パスワードを手動で変更します。これは、スキーマもユーザーであるOracleでよく起こります...
「ティーザーの質問」をすることで、最終的な回答に対する誰かの意見よりも、ディスカッションに興味を持つように見えます。アクティブ(> 2500メンバー)のメーリングリスト agileDatabases はこれらの質問の多くに対処しており、私の経験では、この種の議論のための洗練された市民フォーラムです。
白い塔の議論に入るのではなく、実際の問題で私にとって非常にうまくいった解決策があります。
データベースを最初から構築することは、SQLスクリプトの管理として要約できます。
DBdeployは、データベースの現在の状態をチェックするツールです。以前にそれに対して実行されたスクリプト、実行可能なスクリプト、したがって実行に必要なスクリプト。
次に、必要なすべてのスクリプトをまとめて照合し、実行します。次に、実行されたスクリプトを記録します。
これは最もきれいなツールでも最も複雑なツールでもありませんが、注意深く管理すれば非常にうまく機能します。オープンソースであり、簡単に拡張できます。スクリプトの実行が適切に処理されると、最新のスクリプトをチェックアウトして特定のインスタンスに対してdbdeployを実行するシェルスクリプトなどの追加コンポーネントを簡単に追加できます。
ここで良い紹介を参照してください:
私は、DBはソース管理の一部であり、構築プロセスの大部分を占めるべきであると強く信じています。ソース管理にある場合は、SQLでストアドプロシージャを作成するときに、C#でクラスを作成するときと同じコーディングセーフガードを使用します。これを行うには、ソースツリーの下にDBスクリプトディレクトリを含めます。このスクリプトディレクトリには、データベース内の1つのオブジェクトに対して1つのファイルが必ずしもあるとは限りません。お尻が痛い!私は自分のコードプロジェクトで行うのと同じように、自分のデータベースで開発します。次に、チェックインの準備ができたら、データベースの最後のバージョンと現在作業中のデータベースを比較します。私はこれにSQL Compareを使用し、すべての変更のスクリプトを生成します。次に、このスクリプトを特定の命名規則1234_TasksCompletedInThisIterationを使用して私のdb_updateディレクトリに保存します。ここで、番号は既に存在するスクリプトセットの次の番号であり、名前はこのチェックインで行われていることを示しています。私の構築プロセスの一部として、新しいディレクトリから始めます。このデータベースは、このディレクトリのスクリプトを使用してプログラムで構築されます。私は、裸のdbでコンテンツを実行する各スクリプトを反復処理するカスタムNAntタスクを作成しました。明らかに、dbに入力するデータが必要な場合は、データ挿入スクリプトも用意しています。これには多くの利点もあります。 1つは、私のすべてのものがバージョン管理されていることです。 2つ目は、各ビルドが新鮮なビルドであるため、開発プロセスに悪用されることはありません(システムに奇妙な原因となるダーティデータなど)。 3つ目は、新しいチームが開発チームに追加されたとき、彼らは単に最新のものを入手する必要があり、ローカルの開発者がその場で彼らのために構築されていることです。 4、データベースごとにビルドのたびにデータベースの状態がリセットされるため、データベースでテストケースを実行できます(これを「単体テスト」とは呼びませんでした)。テストデータをdb)。
これは皆のためではありません。
これはすべてのプロジェクトに当てはまるわけではありません。私は通常、この便利さを可能にするグリーンフィールドプロジェクトに取り組んでいます。
すべての開発者は独自のローカルデータベースを持ち、ソースコード管理を使用してチームに公開する必要があります。私の解決策はここにあります: http://dbsourcetools.codeplex.com/ 楽しんでください-Nathan
Liquibase が探しているものの多くを処理することに気付くでしょう。