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


103

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

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

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

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

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

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

3
この質問の深さは、賞金を求めています。
グレッグD

回答:


53

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

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

ご回答有難うございます!これらの推奨事項はすべてのプロジェクトに適用されると思いますか?このレベルの自動化を実現するのに役立つツールを知っていますか?より多くの人々がそれに加わるので、私は私の質問を更新します。また、私の「ティーザー」の質問は、対処すべき懸念事項の決定的なリストではなく、議論の出発点として意図されたものであることに注意してください。
LBushkin 2009年

晴れ。あなたは非常に良い質問をしたと思います。そして、この質問があなたがこのトピックに関する素晴らしいハウツーwikiをコンパイルするのに十分な牽引力を獲得することを本当に望みます。----ツールから:私はMSSQLサーバーを管理するための回答で述べたInnovartisのdbGhostを使用しました。おそらく他の仕事用のツールがあるでしょうが、完全なSQLスキーマがベンダー間で実際に標準ではないことを考えると、オールインワンソリューションはありません(すべてのSCMおよびRDMBSに対して)。
ヴァン

いい答えだ。「リストのルックアップ」とは、<select>ボックスを作成するために使用されるデータを意味すると思いますか?そのデータは本番環境でユーザーによって(何らかの方法で)変更される可能性があるため、常に可能であるとは限りません。この場合、バックアップを保持することは理にかなっています。また、夜間ビルドの一部として、データベースを最初から再作成することをお勧めします。それは良い考えではないと思います。進行中の作業を削除したり、他のソフトウェアの再インストール/設定が必要になる場合があります。最後に、回復力のあるプロセスを保証するためにゼロから構築するのではなく、テストモード、データ検証ツール、およびその他のツールを作成することをお勧めします。
Richard Levasseur

@リチャード。良い点ですが、それでもまだです。「データベースを最初から構築する」を読んだ場合、必ずしもデータを削除することを意味するわけではありません。スキーマと静的データを再構築することです。進行中の作業(スキーマまたは静的データに関して)がある場合は、ソース管理にある必要があるため、ナイトリービルドの一部になります。大規模なDBの再設計を行ってブランチで作業している場合、この種の開発用に別のデータベースがあります。また、単体テストを使用する場合は、データベースのデータステータスに依存せず、db-unit-testの一部として作成/削除します。---ユーザーが消費可能な静的データ-同意します。
ヴァン

毎晩データベースを再構築することに同意しません。スキーマ、トリガー、ストアドプロシージャ、特定の静的な「管理された」データなど、データベースを定義するためのすべてをスクリプト化する必要がありますが、実際のマテリアルはスクリプト化しないでください。コンテンツ自体は、開発者のタスクによって駆動される場合があります。テストと実験のために一連のデータに取り組む開発者がいます。もし彼らが毎日やって来て、彼らの現在の状態が「リセット」されたとしたら?良くない。特定のテーブルを一掃し、毎日テストデータをプリロードするTestNGテストを使用しています。ソース管理の候補のようには聞こえません。
gregturn 2009年

5

可能な場合、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クエリを抽象化します。

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


4

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

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

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

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


4

Liquibaseの +1 : LiquiBaseは、オープンソース(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からのトランク/ブランチをチェックします。そのため、そのマスターは常に一貫しており、本番環境に対応しています。

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


3

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


普遍的に合意された単一の回答に到達できる可能性は低いと思います。しかし、私は合意のいくつかの一般的な分野を特定したいと思います-そしておそらく合理的な勧告を組み立てたいと思います。私は間違いなく、アジャイルデータベースフォーラムも見ていきます、ありがとう。
LBushkin 2009年

3

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

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

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

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

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

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

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

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


1

Gitバージョン管理にMSSQLデータベースを備えたSilverlightプロジェクトがあります。最も簡単な方法は、スリム化されたデータベース(コンテンツに関して)があることを確認し、Visual Studioから完全なダンプを実行することです。次に、ビルドスクリプトから 'sqlcmd'を実行して、各開発マシンでデータベースを再作成できます。

データベースが大きすぎるため、これを展開することはできません。そもそもそれがデータベースにデータベースを置く主な理由です。


1

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

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

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


データベース比較ライフサイクルの一部としてSQL Compareを使用していると聞いて、うれしいです。開発者が新しい変更を簡単に取得できるようになったと思います。SQLソース管理を確認してください。これは、SQL Compareと並行して機能し、開発者のコ​​ラボレーションを容易にするだけでなく、スキーマオブジェクトのソース管理を維持できます(SVNまたはTFSを使用している場合)。red-gate.com/products/sql_source_control/index.htm
David Atkinson、

1

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

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

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

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

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

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

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



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