14

私は現在、ソース管理のないデータベースを使用している開発チームの一員です。SQL Server 2008 R2を使用しており、常にSSMSを使用してDBを直接管理してきました。現在、最大340個のテーブルと最大1600個のストアドプロシージャに加えて、いくつかのトリガーとビューがあるため、小さなDBではありません。

私の目標はDBをバージョン管理下に置くことなので、ScottAllenのシリーズや多くの古いSO関連の質問などの記事を読んでいます。しかし、私はまだどのように進めるかを決めることができません。

私が考えているのは、データベーススキーマを1つのファイルにスクリプト化し、次にプロシージャ、トリガー、およびビューをそれぞれ1つのファイルにスクリプト化することです。次に、すべてをMercurialでバージョン管理します。ただし、もちろん、チームのすべてのメンバーがSSMSにアクセスして、スキーマとプロシージャを直接変更できます。バージョン管理されたファイルにこれらの変更を複製することを忘れてしまう可能性があります。

より良いオプションはありますか?そして、ソース管理する価値のある要素を忘れましたか?私の最大の懸念は、私が見つけたほとんどの文献が、新しいデータベースを作成するときにバージョン管理を行う方法を説明していることですが、データベースがすでに古くて比較的大きい場合は説明していません。

4

5 に答える 5

14

一般的なプロセス

特定のバージョンのベースラインを作成します(たとえばv1.0)。ベースラインには、1つの完全なスキーマ作成スクリプトと、許可されている以前のバージョンからのアップグレードスクリプト(存在する場合)が含まれます(これについては後で詳しく説明します)。したがって、の場合v1.0、スクリプトは1つだけです。

baseline-v1.0.sql

そのベースラインから、前のベースラインから作業するときに増分変更スクリプトを作成します。これらのスクリプトは、再入可能であるように作成されているため、複数回安全に実行できます(最初は実際の作業のみを行います。提案については、次の段落を参照してください)。ベースライン名とタイムスタンプ(バージョンと呼びます)を使用して、変更スクリプトごとにファイルを作成するだけです。たとえば、ベースラインの後に2つの変更スクリプトを作成するとします。次のファイルがあります。

baseline-v1.0.sql (for creating new installations)
baseline-v1.0-201211071220.sql (created on Nov. 7, 2012 at 12:20 PM UTC)
baseline-v1.0-201211122019.sql (created on Nov. 12, 2012 at 8:00 PM UTC)

とのschema_version2つの列を持つテーブルを作成します。は(上記のような)ラベルであり、変更スクリプトが作成されたときのタイムスタンプにすぎません(任意のバージョン番号を作成すると、タイムスタンプが使いやすい管理上のオーバーヘッドが発生するため、これを選択しました)。したがって、変更スクリプトを実行する前に、とでクエリを実行して、変更スクリプトがまだ適用されているかどうかを確認します。すでに存在している場合は、スクリプトなどから戻ってください。それ以外の場合は、変更を適用してテーブルに挿入し、変更スクリプトが完了したことを示します。baselineversionbaselinev1.0versionbaselineversionschema_version

変更スクリプトの例:

-- Created by <developer> on Nov. 7, 2012 at 12:20 PM UTC
declare @schema_baseline varchar(10), @schema_version varchar(12)

set @schema_baseline = 'v1.0'
set @schema_version = '201211071210'

if exists (select 1 from schema_version where baseline = @schema_baseline and version = @schema_version = @schema_version) return 0

-- begin change script

-- place your schema changes here

-- end change script

insert into schema_version(@schema_baseline, @schema_version)

ここで、実際にソフトウェアをインストールするときに、関連するbaselineスクリプトを実行します。そのバージョンをアップグレードするときは、変更スクリプトを順番に適用するだけです。

製品開発フェーズで重要なマイルストーンに到達すると、新しいベースラインを作成します。そのため、新しいベースラインスクリプト(これもベースラインとしてのDBのスナップショットです)に加えて、前のベースラインからのアップグレードスクリプトを作成します。したがって、新しいベースラインがあるとしましょうv2.0。次のファイルがあります。

baseline-v2.0.sql (for creating new installations)
baseline-v2.0-upgrade-v1.0.sql (for upgrading from v1.0)

その後、プロセスが続行されます。

変更の適用方法

スクリプトはすべてソース管理されています。これらのファイルをパッケージ化し、データベースを自動的にアップグレードするツールがあります。これは、サポートチームとインストールチームが使用します。このツールは、ターゲットデータベースの現在のベースラインを把握し、パッケージ内のベースラインにアップグレードするかどうかをユーザーに尋ねます。もしそうなら、そして現在のバージョンからの有効なアップグレードパスがある場合、それはアップグレードスクリプトを適用し、schema_version.baseline、および変更スクリプトのすべてのエントリを前のベースラインから削除します。データベースが新しい場合は、通常のベースラインスクリプトが適用されます。いずれにせよ、ベースラインが達成された後、パッケージに存在するベースラインからのすべての変更スクリプトを、トランザクションで一度に1つずつ順番に適用します。特定の変更スクリプトが失敗すると、最後の変更とエラーのセットがロールバックされます。ログを確認し、問題を修正してから、パッケージを再実行します。その時点で、成功した最後の変更スクリプトを取得するだけで、時間を節約できます。

自動化および差分ツール

差分ツールが本番データベースを直接アップグレードすることは許可されていません。リスクが高すぎます。もちろん、アップグレードと変更のスクリプトを作成するために差分ツールを使用しますが、それらを取得したら、それらをくまなく調べ、マッサージし、テストするなどして、上記の仕様に従ってアップグレードまたは変更のスクリプトを作成します。ツール/シェルスクリプトを使用して変更スクリプトファイルを作成し、ボイラープレートschema_versionチェックを行います。

警告

それは実際にはかなり簡単で、うまく機能します。それが本当にトリッキーになるのは、ブランチを使用する場合だけです。ほとんどの場合、ブランチは適切に処理されます。特定のブランチの作業に変更スクリプトが必要な場合は、ブランチをマージして戻すと、メインラインにうまく折りたたまれます。問題ありません。トリッキーになるのは、2つのブランチが同様のことを行おうとする場合、または1つのブランチが別のブランチに依存する場合です。ただし、これは主にプロセスと計画の問題です。このような状況で行き詰まった場合は、新しいベースライン(たとえばv2.1)を作成し、それに応じてブランチを更新します。

もう1つ覚えておくべきことは、インストールをあるベースラインから別のベースラインにアップグレードする場合は、新しいベースラインにアップグレードする前に、現在のベースラインにすべての未解決の変更を適用する必要があるということです。つまり、インストールがどこからでも次のベースラインにジャンプすることはありません(もちろん、現在のベースラインの最新バージョンになっている場合を除きます)。

于 2012-11-07T17:54:23.750 に答える
11

SQLServerデータツールやVisualStudioSQLデータベースプロジェクトをお勧めします。これにより、既存のDBがバージョン管理可能なcode(sql)ファイルにリバースエンジニアリングされ、他の多くの機能(公開、比較など)が提供されます。

于 2012-11-07T17:07:27.007 に答える
5

あなたが説明する問題を解決するために、SQLソース管理を特別に開発しました。SSMSを拡張して、SQL Serverスキーマオブジェクト(および静的データ)と既存のソース管理システム間のリンクを提供します。

http://www.red-gate.com/products/sql-development/sql-source-control/

さらに詳しい情報が必要な場合は、喜んでサポートさせていただきます(support@red-gate.comまでお問い合わせください)。

于 2012-11-30T08:56:31.513 に答える
3

多くの開発者フォーラムで、このトピックに関して多くの議論がありました。

私が行って、最も簡単でクリーンな方法であることがわかったのは、これです。

  1. すべてのDBオブジェクトのDDLを独自のファイルに抽出します。インデックスとPKは、それらが属するテーブルと同じファイルに入れることができます。FK、プロシージャ、ビュー、トリガー、複数のテーブルにまたがることができるものはすべて、独自のファイルに入れられます。

  2. DDLファイルをオブジェクトタイプ(テーブル、プロシージャ、トリガー、ビューなど)ごとにdirsで整理します。

  3. 静的参照データ(郵便番号や州など)を保持するテーブルの場合は、一連の挿入ステートメントを含む別のファイルを用意します

  4. このディレクトリ構造を、使用しているバージョン管理にチェックインしてください

  5. DBをイメージ化するこのディレクトリ構造をトラバースし、ポイントする実際のDBと差分を取り(システムテーブルからスキーマを抽出)、ALTERTABLEステートメントを使用して差分を適用するスクリプトを記述します。

  6. リリース間でデータ変換を行う場合、たとえばv1ではフィールドFirstAndLastNameがあり、v2ではそれをFirstNameとLastNameに分割することにした場合、バルクデータ移行/処理ステートメントがあります。

いくつかの異なるRDBMSを使用して、いくつかのジョブでDBの変更を正常に管理しました。私は通常、イメージ内のDBスキーマとDDLファイルを比較するスクリプトにPerlを使用します。この方法にはいくつかの前提条件があり、そのうちの1つは、DBに直接変更を加えることはなく、DDLファイルに変更を加えてから、スクリプトを実行して適用することです。逆の場合は、スクリプトを実行したときに元に戻されます。したがって、チームの合意と規律が必要です。マイレージは異なる場合があります。

さて、あなたのためにこれを行うFOSSツールがそこにあるなら、あなた自身のものを考案するのではなく、ぜひそれを使ってください。私はこの方法で10年以上やっています

于 2012-11-07T17:32:03.470 に答える
-1

私たちのSQLHistorianソース管理システムは、特にチームメートがサーバーを更新した後にコードをチェックインするのを「忘れる」という状況で、この問題を抱えている人々を助けることができます。

これはバックグラウンドにあり、ユーザーが何もチェックインすることなく、dbオブジェクトに加えられたすべての変更をソース管理に記録します。飛行機のブラックボックスレコーダーのように考えて、必要になるまで邪魔にならないようにします。

于 2015-02-04T16:58:36.097 に答える