web-dev-qa-db-ja.com

ソース管理からデータベースをどのように構築すべきですか?

SOコミュニティウィキでは、データベースオブジェクトをバージョン管理する必要があるかどうかについて、いくつかの議論がありました。しかし、のベストプラクティスについては、あまり議論していませんデータベースオブジェクトのビルド自動化プロセスを作成します。

特に、開発者とDBAは、データベース展開への自動化アプローチのメリットとリスクを評価するときに、異なる目標、アプローチ、および懸念を抱くことが多いため、これは私のチームにとって議論の的となっています。

SOコミュニティから、現実の世界でどのような実践が効果的だったかについて、いくつかのアイデアを聞きたいと思います。

どのプラクティスが本当に最良であるかはやや主観的であると私は理解していますが、私は多くの人々にとってどのような仕事が役立つかについての良い対話を考えています。

これは、このトピックの懸念事項に関する私のティーザーの質問の一部です。これらは完全なリストではなく、人々が私が探しているものを理解するための出発点です。

  1. テスト環境と本番環境の両方をソース管理から構築する必要がありますか?
    • 両方とも自動化を使用して構築する必要がありますか、それとも、安定した最終的なテスト環境からオブジェクトをコピーすることによって構築する必要がありますか?
    • 展開スクリプトのテスト環境と本番環境の潜在的な違いにどのように対処しますか?
    • 展開スクリプトがテストと同じくらい効果的に運用環境に対して機能することをどのようにテストしますか?
  2. どのタイプのオブジェクトをバージョン管理する必要がありますか?
    • ちょうどコード(手順、パッケージ、トリガー、Javaなど)?
    • インデックス?
    • 制約?
    • テーブル定義?
    • テーブル変更スクリプト? (例:ALTERスクリプト)
    • 全部?
  3. バージョン管理すべきではないオブジェクトのタイプはどれですか?
    • シーケンス?
    • 助成金?
    • ユーザーアカウント?
  4. SCMリポジトリでデータベースオブジェクトをどのように編成する必要がありますか?
    • 変換スクリプトやALTERスクリプトなど、一度きりのものにどのように対処しますか?
    • データベースからオブジェクトを廃棄する方法を教えてください。
    • オブジェクトの開発からテストレベルへの昇格の責任者は誰ですか?
    • 複数の開発者による変更をどのように調整しますか?
    • 複数のシステムで使用されるデータベースオブジェクトの分岐をどのように処理しますか?
  5. このプロセスに妥当な例外があれば、どのような例外がありますか?
    • セキュリティ上の問題?
    • 匿名化の懸念があるデータ?
    • 完全に自動化できないスクリプト?
  6. どのようにしてプロセスに回復力と強制力を持たせることができますか?
    • 開発者のエラーに?
    • 予期せぬ環境問題へ?
    • 災害復旧のために?
  7. DB-SCMのメリットがコストを正当化するものであると意思決定者にどのように説得しますか?
    • 事例証拠?
    • 業界調査?
    • 業界のベストプラクティスの推奨事項?
    • 認められた当局に訴えますか?
    • 費用便益分析?
  8. このモデルで誰がデータベースオブジェクトを「所有」する必要がありますか?
    • 開発者?
    • DBA?
    • データアナリスト?
    • 複数の?
102
LBushkin

ここにあなたの質問に対するいくつかの答えがあります:

  1. テスト環境と本番環境の両方をソース管理から構築する必要がありますか? [〜#〜]はい[〜#〜]
    • どちらも自動化を使用して構築する必要がありますか、それとも、安定した最終的なテスト環境からオブジェクトをコピーして構築することによって本番環境で構築する必要がありますか?
    • 両方のオートメーション。環境間でデータをコピーしないでください
    • 展開スクリプトのテスト環境と本番環境の潜在的な違いにどのように対処しますか?
    • テンプレートを使用して、実際に環境ごとに異なるスクリプトのセットを作成します(例:外部システム、リンクされたデータベースなどへの参照)
    • 展開スクリプトがテストと同じように本番環境に対して効果的に機能することをどのようにテストしますか?
    • 運用前の環境でそれらをテストします:運用環境の正確なコピー(データベースおよびその他のシステム)で展開をテストします
  2. どのタイプのオブジェクトをバージョン管理する必要がありますか?
    • ちょうどコード(手順、パッケージ、トリガー、Javaなど)?
    • インデックス?
    • 制約?
    • テーブル定義?
    • テーブル変更スクリプト? (例:ALTERスクリプト)
    • 全部?
    • すべて、および:
      • 静的データ(ルックアップリストなど)を忘れないでください。環境間でデータをコピーする必要はありません
      • データベーススクリプトの現在のバージョンのみを保持します(もちろん、バージョン管理されています)、および
      • Store ALTERスクリプト:1つのBIGスクリプト(または、liked 001_AlterXXX.sqlという名前のスクリプトのディレクトリ。これにより、自然なソート順で実行すると、バージョンAからBにアップグレードされます)
  3. バージョン管理すべきではないオブジェクトのタイプはどれですか?
    • シーケンス?
    • 助成金?
    • ユーザーアカウント?
    • を参照してください。2。ユーザー/ロール(またはテクニカルユーザー名)が環境間で異なる場合でも、テンプレートを使用してスクリプトを作成できます(1.を参照)
  4. SCMリポジトリでデータベースオブジェクトをどのように編成する必要がありますか?
    • 変換スクリプトやALTERスクリプトなどの一時的なものをどのように処理しますか?
    • 2を参照してください。
    • データベースからオブジェクトを廃棄する方法を教えてください。
    • DBから削除、ソース管理トランク/チップから削除
    • オブジェクトを開発からテストレベルに昇格させるのはだれですか。
    • dev/test/release schedule
    • 複数の開発者による変更をどのように調整しますか?
    • 開発者ごとに個別のデータベースを作成しないでください。ソース管理を使用しますよね?この場合、開発者はデータベースを変更し、スクリプトをチェックインします。完全に安全にするために、夜間のビルド中にスクリプトからデータベースを再作成します
    • 複数のシステムで使用されるデータベースオブジェクトの分岐をどのように処理しますか?
    • タフな1つ:絶対に避けてください
  5. このプロセスに妥当な例外があれば、どのような例外がありますか?
    • セキュリティ上の問題?
    • test/prodのパスワードを保存しません。特に毎日/毎晩のDB再構築を自動化している場合は、開発にそれを許可することができます
    • 匿名化の懸念があるデータ?
    • 完全に自動化できないスクリプト?
    • リリース情報/ ALTERスクリプトでドキュメントとストア
  6. どのようにしてプロセスに回復力と強制力を持たせることができますか?
    • 開発者のエラーに?
    • ゼロからの毎日のビルドでテストし、結果を増分アップグレード(ALTERを使用してバージョンAからBに)と比較します。結果のスキーマと静的データの両方を比較します
    • 予期せぬ環境問題へ?
    • バージョン管理とバックアップを使用します
    • 特に配置の前に、PRODデータベースのスキーマを、あなたが思っているものと比較してください。 SuperDuperCool DBAが、チケットシステムにはなかったバグを修正した可能性があります:)
    • 災害復旧のために?
  7. DB-SCMの利点がコストを正当化するものであることを意思決定者にどのように説得しますか?
    • 事例証拠?
    • 業界調査?
    • 業界のベストプラクティスの推奨事項?
    • 認められた当局に訴えますか?
    • 費用便益分析?
    • 開発者とDBAが同意すれば、だれも納得させる必要はないと思います(MSSQL用の dbGhost のようなソフトウェアを購入するのにお金が必要でない限り)
  8. このモデルで誰がデータベースオブジェクトを「所有」する必要がありますか?
    • 開発者?
    • DBA?
    • データアナリスト?
    • 複数の?
    • 通常、DBAはモデルを承認します(チェックイン前またはコードレビューの一部として後)。彼らは確かにパフォーマンス関連のオブジェクトを所有しています。しかし、一般的にチームはそれを所有しています[そしてもちろん雇用主:)]
53
van

可能な場合はSQLをソースコードとして扱います

標準に準拠したSQLで記述できる場合、通常はソース管理のファイルに入ります。ファイルは、SP、テーブルCREATEステートメントなど、できるだけ多くを定義します。

ソース管理でテストするためのダミーデータも含めます。

  1. proj/sql/setup_db.sql
  2. proj/sql/dummy_data.sql
  3. proj/sql/mssql_specific.sql
  4. proj/sql/mysql_specific.sql

その後、MySQL、Oracle、MSSQLなどのプロジェクト全体を構築できるように、すべてのSQLクエリを抽象化します。

ビルドとテストの自動化では、これらのビルドスクリプトをアプリのソースと同じくらい重要として使用し、整合性からトリガー、手順、ロギングまですべてをテストします。

5
Aiden Bell

TeamCityを介した継続的な統合を使用しています。ソース管理にチェックインするたびに、データベースとすべてのテストデータが最初から再構築され、次にコードが再構築され、コードに対してユニットテストが実行されます。 CodeSmithなどのコード生成ツールを使用している場合は、それをビルドプロセスに配置して、各ビルドでデータアクセスレイヤーを新しく生成し、すべてのレイヤーが「一致」し、エラーが発生しないようにすることができます。 SPパラメータが一致していないか、列がありません。

各ビルドには、ソース管理の$ project\SQL \ディレクトリに保存されたSQLスクリプトの独自のコレクションがあり、数値のプレフィックスが割り当てられ、順番に実行されます。このようにして、すべてのビルドで展開手順を実践しています。

ルックアップテーブルによっては、ほとんどのルックアップ値もスクリプトに格納され、構成データが、たとえば「reason_codes」や「country_codes」に期待されるものであることを確認するために実行されます。このように、ツールを使用して本番環境でルックアップ値を変更する代わりに、開発でルックアップデータを変更してテストし、QAと本番環境を介して「昇格」させることができます。

また、本番環境へのビルドが不安定になった場合に備えて、データベースの変更を取り消す一連の「ロールバック」スクリプトを作成します。ロールバックスクリプトを実行してテストし、その後、配置スクリプトの実行後に、ビルドのユニットテストを1つ下のバージョンで再実行できます。

4
Chris McCall

+1 forLiquibaseLiquiBase は、オープンソース(LGPL)であり、データベースを追跡、管理、適用するためのデータベースに依存しないライブラリです変更。シンプルな前提に基づいて構築されています。すべてのデータベースの変更(構造とデータ)は、XMLベースの記述的な方法で保存され、ソース管理にチェックインされます。良い点は、DMLの変更が差分だけでなく意味的に保存されるため、変更の目的を追跡できることです。

[〜#〜] git [〜#〜] と組み合わせると、より良い対話が可能になります。それを試すためにdev-prod環境を構成します。

また、スクリプトからプロダクションコードをビルドするためにMaven、Antビルドシステムを使用することもできます。

マイナス点は、LiquiBaseが広範なSQL IDEに統合されておらず、基本的な操作を自分で行う必要があることです。

これに加えて、DBテストに DBUnit を使用できます-このツールにより、データ生成スクリプトを使用して本番環境をテストできますクリーンアップを伴う環境。

私見では:

  1. DMLをファイルに保存して、バージョン管理できるようにします。
  2. ソース管理からスキーマ構築プロセスを自動化します。
  3. テストの目的で、開発者はビルドシステムを介してソースコントロールからビルドされたローカルDBを使用し、スクリプトでテストデータをロードするか、またはDBUnitスクリプト(ソースコントロールから)を使用できます。
  4. LiquiBaseを使用すると、依存関係を尊重するスクリプトの「実行シーケンス」を提供できます。
  5. 本番環境で使用する前に、すべての変更でマスターブランチをチェックするDBAチームが必要です。つまり、MASTERトランクにコミットする前に、他のDBAのトランク/ブランチをチェックします。そのため、そのマスターは常に一貫しており、本番環境に対応しています。

請求書作成データベースでのコード変更、マージ、リライトに関する前述のすべての問題に直面しました。このトピックは、それらすべてを発見するのに最適です。

4
zmische

私は基本的に van によって与えられるすべての答えに同意します。より深い洞察として、私のデータベース管理のベースラインは K。スコットアレンシリーズ です(必読です、私見です。そして ジェフの意見 もそうです)。

  • データベースオブジェクトは、単一のSQLファイル(それ自体が他のSQLファイルを呼び出すことができる)を起動することにより、常に最初から再構築できます:Create.sql。これには、staticデータ挿入(リスト...)を含めることができます。
  • SQLスクリプトはパラメーター化されているため、環境に依存する情報や機密情報がプレーンファイルに保存されることはありません。
  • カスタムバッチファイルを使用してCreate.sqlCreate.cmdを起動します。その目的は主に、前提条件(ツール、環境変数...)をチェックし、SQLスクリプトにパラメーターを送信することです。パフォーマンスの問題のために、CSVファイルから静的データをbulk-loadすることもできます。
  • 通常、システムユーザーの資格情報は、パラメータとしてCreate.cmdファイルに渡されます。

IMHO、dynamicデータのロードには、環境に応じて別の手順が必要です。開発者は、テスト、ジャンク、またはまったくデータなしでデータベースをロードする必要がありますが、もう一方の端では、プロダクションマネージャーはプロダクションデータをロードする必要があります。 (たとえば、単体テストを容易にするために)ソース管理にもテストデータを格納することを検討します。

データベースの最初のバージョンが本番環境に配置されると、スクリプト(主に開発者向け)をビルドするだけでなく、(同じ原則に基づいて)アップグレードスクリプトも必要になります。

  • データベースからバージョンを取得する方法が必要です(私はストアドプロシージャを使用していますが、テーブルも同様です)。
  • 新しいバージョンをリリースする前に、バージョンN-1をバージョンN(Nはリリースされるバージョン)にアップグレードできるUpgrade.sqlファイル(他のファイルを呼び出すことができる)を作成します。このスクリプトはN-1という名前のフォルダーに保存します。
  • アップグレードを行うバッチファイルUpgrade.cmdがあります。単純なSELECTステートメントを使用してデータベースの現在のバージョン(CV)を取得し、CVフォルダーに保存されているUpgrade.sqlスクリプトを起動して、フォルダーが見つからなくなるまでループできます。このようにして、たとえばN-3からNに自動的にアップグレードできます。

これに関する問題は次のとおりです。

  • データベースベンダーによっては、データベーススキーマを自動的に比較することは困難です。これにより、アップグレードスクリプトが不完全になる可能性があります。
  • 本番環境へのすべての変更(通常、パフォーマンスチューニングのためにDBAが行う)は、ソース管理にも反映されます。これを確認するために、トリガーを介してデータベースへのすべての変更をログに記録することが通常可能です。このログは、アップグレードのたびにリセットされます。
  • ただし、より理想的には、DBAが開始した変更は、可能な場合はリリース/アップグレードプロセスの一部である必要があります。

どのようなデータベースオブジェクトをソース管理下に置きたいですか?ええと、私はできる限り多く言いますが、それ以上は言いません;-)パスワードを使用してユーザーを作成する場合は、デフォルトのパスワード(ログイン/ログイン、単体テストの目的で実用的)を取得し、パスワードを手動で変更します。これは、スキーマもユーザーであるOracleでよく起こります...

3
Mac

「ティーザーの質問」をすることで、最終的な回答に対する誰かの意見よりも、ディスカッションに興味を持つように見えます。アクティブ(> 2500メンバー)のメーリングリスト agileDatabases はこれらの質問の多くに対処しており、私の経験では、この種の議論のための洗練された市民フォーラムです。

3
Glenn

白い塔の議論に入るのではなく、実際の問題で私にとって非常にうまくいった解決策があります。

データベースを最初から構築することは、SQLスクリプトの管理として要約できます。

DBdeployは、データベースの現在の状態をチェックするツールです。以前にそれに対して実行されたスクリプト、実行可能なスクリプト、したがって実行に必要なスクリプト。

次に、必要なすべてのスクリプトをまとめて照合し、実行します。次に、実行されたスクリプトを記録します。

これは最もきれいなツールでも最も複雑なツールでもありませんが、注意深く管理すれば非常にうまく機能します。オープンソースであり、簡単に拡張できます。スクリプトの実行が適切に処理されると、最新のスクリプトをチェックアウトして特定のインスタンスに対してdbdeployを実行するシェルスクリプトなどの追加コンポーネントを簡単に追加できます。

ここで良い紹介を参照してください:

http://code.google.com/p/dbdeploy/wiki/GettingStarted

1
Pablojim

私は、DBはソース管理の一部であり、構築プロセスの大部分を占めるべきであると強く信じています。ソース管理にある場合は、SQLでストアドプロシージャを作成するときに、C#でクラスを作成するときと同じコーディングセーフガードを使用します。これを行うには、ソースツリーの下にDBスクリプトディレクトリを含めます。このスクリプトディレクトリには、データベース内の1つのオブジェクトに対して1つのファイルが必ずしもあるとは限りません。お尻が痛い!私は自分のコードプロジェクトで行うのと同じように、自分のデータベースで開発します。次に、チェックインの準備ができたら、データベースの最後のバージョンと現在作業中のデータベースを比較します。私はこれにSQL Compareを使用し、すべての変更のスクリプトを生成します。次に、このスクリプトを特定の命名規則1234_TasksCompletedInThisIterationを使用して私のdb_updateディレクトリに保存します。ここで、番号は既に存在するスクリプトセットの次の番号であり、名前はこのチェックインで行われていることを示しています。私の構築プロセスの一部として、新しいディレクトリから始めます。このデータベースは、このディレクトリのスクリプトを使用してプログラムで構築されます。私は、裸のdbでコンテンツを実行する各スクリプトを反復処理するカスタムNAntタスクを作成しました。明らかに、dbに入力するデータが必要な場合は、データ挿入スクリプトも用意しています。これには多くの利点もあります。 1つは、私のすべてのものがバージョン管理されていることです。 2つ目は、各ビルドが新鮮なビルドであるため、開発プロセスに悪用されることはありません(システムに奇妙な原因となるダーティデータなど)。 3つ目は、新しいチームが開発チームに追加されたとき、彼らは単に最新のものを入手する必要があり、ローカルの開発者がその場で彼らのために構築されていることです。 4、データベースごとにビルドのたびにデータベースの状態がリセットされるため、データベースでテストケースを実行できます(これを「単体テスト」とは呼びませんでした)。テストデータをdb)。

これは皆のためではありません。

これはすべてのプロジェクトに当てはまるわけではありません。私は通常、この便利さを可能にするグリーンフィールドプロジェクトに取り組んでいます。

1
Andrew Siemer

すべての開発者は独自のローカルデータベースを持ち、ソースコード管理を使用してチームに公開する必要があります。私の解決策はここにあります: http://dbsourcetools.codeplex.com/ 楽しんでください-Nathan

0

Liquibase が探しているものの多くを処理することに気付くでしょう。

0
David Plumpton