データベースをバージョン管理下に置きたいのですが。私を始めるためのアドバイスや推奨記事はありますか?
私は常にそこに少なくともいくつかのデータを入れたいと思っています(alumbの言及のように:ユーザータイプと管理者)。また、パフォーマンス測定のために生成されたテストデータの大規模なコレクションが必要になることもよくあります。
データベースをバージョン管理下に置きたいのですが。私を始めるためのアドバイスや推奨記事はありますか?
私は常にそこに少なくともいくつかのデータを入れたいと思っています(alumbの言及のように:ユーザータイプと管理者)。また、パフォーマンス測定のために生成されたテストデータの大規模なコレクションが必要になることもよくあります。
回答:
マーティン・ファウラーがこのテーマについて私のお気に入りの記事を書いた、http://martinfowler.com/articles/evodb.html。本番データベースをアップグレードする簡単な方法が欲しいので、alumbや他の人が示唆するように、スキーマダンプをバージョン管理下に置かないことにしました。
単一の本番データベースインスタンスを使用するWebアプリケーションの場合、2つの手法を使用します。
スキーマをバージョンNからN + 1に移動するために必要なDDLを含むシーケンスデータベースアップグレードスクリプト。(これらはバージョン管理システムにあります。)_version_history_テーブル、以下のようなもの
create table VersionHistory (
Version int primary key,
UpgradeStart datetime not null,
UpgradeEnd datetime
);
新しいバージョンに対応するアップグレードスクリプトが実行されるたびに、新しいエントリを取得します。
これにより、データベーススキーマのどのバージョンが存在するかを簡単に確認でき、データベースアップグレードスクリプトが1回だけ実行されます。繰り返しますが、これらはデータベースのダンプではありません。むしろ、各スクリプトは、あるバージョンから次のバージョンに移動するために必要な変更を表しています。これらは、本番データベースに「アップグレード」するために適用するスクリプトです。
注意:自動テストはスキーマは正しいが空のデータベースに対して実行されるため、このアドバイスはニーズに完全には適合しません。
Red GateのSQL Compare製品を使用すると、オブジェクトレベルの比較を実行して変更スクリプトを生成できるだけでなく、[objectname] .sqlを1つ作成するだけで、データベースオブジェクトをオブジェクトタイプごとに整理されたフォルダ階層にエクスポートできます。これらのディレクトリのオブジェクトごとのスクリプト。オブジェクトタイプの階層は次のとおりです。
\ Functions
\ Security
\ Security \ Roles
\ Security \ Schemas
\ Security \ Users
\ Stored Procedures
\ Tables
変更後にスクリプトを同じルートディレクトリにダンプした場合、これを使用してSVNリポジトリを更新し、各オブジェクトの実行履歴を個別に保持できます。
これは、開発を取り巻く「難しい問題」の1つです。私の知る限り、完璧な解決策はありません。
データではなくデータベース構造のみを保存する必要がある場合は、データベースをSQLクエリとしてエクスポートできます。(Enterprise Managerの場合:データベースを右クリック-> SQLスクリプトを生成。オプションタブで「オブジェクトごとに1つのファイルを作成する」を設定することをお勧めします)次に、これらのテキストファイルをsvnにコミットし、svnの差分機能とロギング機能を利用できます。
これを、いくつかのパラメーターを取得してデータベースをセットアップするBatchスクリプトと結び付けています。また、ユーザータイプや管理ユーザーなどのデフォルトデータを入力するクエリをいくつか追加しました。(これに関する詳細が必要な場合は、何か投稿してください。スクリプトをアクセス可能な場所に配置できます)
すべてのデータも保持する必要がある場合は、データベースのバックアップを保持し、Redgate(http://www.red-gate.com/)製品を使用して比較を行うことをお勧めします。彼らは安くはありませんが、彼らはあらゆるペニーの価値があります。
まず、適切なバージョン管理システムを選択する必要があります。
一元化されたバージョン管理システム-ユーザーがファイルを操作する前/後にチェックアウト/チェックインし、ファイルが単一の中央サーバーに保持される標準システム
分散バージョン管理システム-リポジトリがクローンされているシステムで、各クローンは実際にはリポジトリの完全バックアップなので、サーバーがクラッシュした場合、クローンされたリポジトリを使用して復元できます。ニーズに合った適切なシステムを選択した後、すべてのバージョン管理システムの中核となるリポジトリをセットアップする必要があります。これはすべて、次の記事で説明されています。http://solutioncenter.apexsql.com/sql-server-source-control-part-i-understanding -source-control-basics /
リポジトリをセットアップした後、中央バージョン管理システムの場合は作業フォルダーについて、この記事を読むことができます。以下を使用して、開発環境でソース管理をセットアップする方法を示します。
MSSCCIプロバイダー経由のSQL Server Management Studio
Visual StudioおよびSQL Serverデータツール
ここRed Gate では、SQL Compareテクノロジーを使用してデータベースをTFSまたはSVNリポジトリにリンクするSQLソース管理ツールを提供しています。このツールはSSMSに統合され、オブジェクトをコミットできるようになる以外は、通常どおりに作業できます。
移行ベースのアプローチ(自動デプロイメントにより適している)のために、一連の増分スクリプトをVisual Studioプロジェクトとして作成および管理するSQL Change Automation(旧称ReadyRoll)を提供しています。
SQLソース管理では、静的データテーブルを指定できます。これらはINSERTステートメントとしてソース管理に保存されます。
テストデータについて話している場合は、ツールを使用するか、定義した展開後のスクリプトを使用してテストデータを生成するか、単に本番環境のバックアップを開発環境に復元することをお勧めします。
Liquibase(http://www.liquibase.org/)を見たいと思うかもしれません。ツール自体を使用しなくても、データベースの変更管理やリファクタリングの概念を適切に処理します。
RedGateツールを推奨するすべてのユーザーに+1、追加の推奨事項と警告を付けます。
SqlCompareには、きちんとドキュメント化されたAPIもあります。たとえば、チェックイン時にソース管理スクリプトフォルダーをCI統合テストデータベースと同期するコンソールアプリを作成して、誰かがスクリプトフォルダーからスキーマへの変更をチェックインすると、対応するアプリケーションコードの変更とともに自動的にデプロイされます。これは、ローカルdbの変更を共有開発DBに伝播することを忘れている開発者とのギャップを埋めるのに役立ちます(私たちの約半分、と思います:))。
スクリプト化されたソリューションなどを使用すると、RedGateツールは十分にスムーズであり、抽象化の基礎となるSQLの現実を忘れがちです。テーブル内のすべての列の名前を変更すると、SqlCompareは古い列を新しい列にマップする方法がなく、テーブル内のすべてのデータを削除します。それは警告を生成しますが、人々がそれを過ぎてクリックするのを見ました。ここで作成する価値のある一般的なポイントがあると思います。これまでのところ、DBのバージョン管理とアップグレードのみを自動化できると思います。抽象化は非常に漏れやすいものです。
変更スクリプトを使用してデータベーススクリプトをバージョン管理に保存し、お持ちの任意の1つのデータベースをアップグレードできるようにすることをお勧めします。また、すべての変更スクリプトを適用せずに完全なデータベースを作成できるように、異なるバージョンのスキーマを保存することもできます。スクリプトの処理は自動化する必要があるため、手動で作業する必要はありません。
開発者ごとに個別のデータベースを用意し、共有データベースを使用しないことが重要だと思います。このようにして、開発者は他の開発者から独立してテストケースと開発フェーズを作成できます。
自動化ツールには、データベースのメタデータを処理する手段が必要です。これにより、どのデータベースがどの開発状態にあり、どのテーブルにバージョン管理可能なデータが含まれるかなどがわかります。
ターゲット環境または制約の詳細については言及しなかったため、これは完全には適用できない可能性があります...しかし、進化するDBスキーマを効果的に追跡する方法を探していて、使用する考えに悪影響がない場合Ruby、ActiveRecordの移行は、まさにその通りです。
移行では、Ruby DSLを使用してデータベース変換をプログラムで定義します。各変換を適用または(通常は)ロールバックできるため、任意の時点でDBスキーマの異なるバージョンにジャンプできます。これらの変換を定義するファイルは、他のソースコードと同様にバージョン管理にチェックインできます。
移行はActiveRecordの一部であるため、通常、フルスタックのRailsアプリで使用されます。ただし、最小限の労力でRailsから独立してActiveRecordを使用できます。Rails外でのARの移行の使用に関するより詳細な扱いについては、こちらを参照してください。
すべてのデータベースはソースコード管理下にある必要があります。不足しているのは、すべてのデータベースオブジェクト(および「構成データ」)をファイルに自動的にスクリプト化するツールで、これをソース管理システムに追加できます。SQL Serverを使用している場合、私の解決策はhttp://dbsourcetools.codeplex.com/です。楽しんで。-ネイサン。
それは簡単です。
ベースプロジェクトの準備ができたら、完全なデータベーススクリプトを作成する必要があります。このスクリプトはSVNにコミットされています。初版です。
その後、すべての開発者が変更スクリプト(ALTER ...、新しいテーブル、sprocsなど)を作成します。
現在のバージョンが必要な場合は、すべての新しい変更スクリプトを実行する必要があります。
アプリが製品版にリリースされると、1に戻ります(ただし、もちろんそれは連続バージョンになります)。
Nantは、これらの変更スクリプトを実行するのに役立ちます。:)
そして覚える。規律がある場合、すべてが正常に動作します。データベースの変更がコミットされるたびに、コード内の対応する関数もコミットされます。
小さなデータベースがあり、全体をバージョン管理する場合は、このバッチスクリプトが役立つ場合があります。MSSQLデータベースのMDFファイルをSubversionにデタッチ、圧縮、およびチェックします。
主にスキーマのバージョン管理を行い、少量の参照データのみを必要とする場合は、SubSonicマイグレーションを使用して処理できます。そこには、特定のバージョンに簡単に移行できるという利点があります。
ソースコード管理システムへのダンプを少し速くするために、sysobjectsのバージョン情報を使用して、前回からどのオブジェクトが変更されたかを確認できます。
セットアップ:増分チェックする各データベースにテーブルを作成し、前回チェックしたとき(最初の実行では空)のバージョン情報を保持します。データ構造全体を再スキャンする場合は、このテーブルをクリアします。
IF ISNULL(OBJECT_ID('last_run_sysversions'), 0) <> 0 DROP TABLE last_run_sysversions
CREATE TABLE last_run_sysversions (
name varchar(128),
id int, base_schema_ver int,
schema_ver int,
type char(2)
)
通常の実行モード:このsqlから結果を取得し、関心のあるものだけのsqlスクリプトを生成して、選択したソースコントロールに配置できます。
IF ISNULL(OBJECT_ID('tempdb.dbo.#tmp'), 0) <> 0 DROP TABLE #tmp
CREATE TABLE #tmp (
name varchar(128),
id int, base_schema_ver int,
schema_ver int,
type char(2)
)
SET NOCOUNT ON
-- Insert the values from the end of the last run into #tmp
INSERT #tmp (name, id, base_schema_ver, schema_ver, type)
SELECT name, id, base_schema_ver, schema_ver, type FROM last_run_sysversions
DELETE last_run_sysversions
INSERT last_run_sysversions (name, id, base_schema_ver, schema_ver, type)
SELECT name, id, base_schema_ver, schema_ver, type FROM sysobjects
-- This next bit lists all differences to scripts.
SET NOCOUNT OFF
--Renamed.
SELECT 'renamed' AS ChangeType, t.name, o.name AS extra_info, 1 AS Priority
FROM sysobjects o INNER JOIN #tmp t ON o.id = t.id
WHERE o.name <> t.name /*COLLATE*/
AND o.type IN ('TR', 'P' ,'U' ,'V')
UNION
--Changed (using alter)
SELECT 'changed' AS ChangeType, o.name /*COLLATE*/,
'altered' AS extra_info, 2 AS Priority
FROM sysobjects o INNER JOIN #tmp t ON o.id = t.id
WHERE (
o.base_schema_ver <> t.base_schema_ver
OR o.schema_ver <> t.schema_ver
)
AND o.type IN ('TR', 'P' ,'U' ,'V')
AND o.name NOT IN ( SELECT oi.name
FROM sysobjects oi INNER JOIN #tmp ti ON oi.id = ti.id
WHERE oi.name <> ti.name /*COLLATE*/
AND oi.type IN ('TR', 'P' ,'U' ,'V'))
UNION
--Changed (actually dropped and recreated [but not renamed])
SELECT 'changed' AS ChangeType, t.name, 'dropped' AS extra_info, 2 AS Priority
FROM #tmp t
WHERE t.name IN ( SELECT ti.name /*COLLATE*/ FROM #tmp ti
WHERE NOT EXISTS (SELECT * FROM sysobjects oi
WHERE oi.id = ti.id))
AND t.name IN ( SELECT oi.name /*COLLATE*/ FROM sysobjects oi
WHERE NOT EXISTS (SELECT * FROM #tmp ti
WHERE oi.id = ti.id)
AND oi.type IN ('TR', 'P' ,'U' ,'V'))
UNION
--Deleted
SELECT 'deleted' AS ChangeType, t.name, '' AS extra_info, 0 AS Priority
FROM #tmp t
WHERE NOT EXISTS (SELECT * FROM sysobjects o
WHERE o.id = t.id)
AND t.name NOT IN ( SELECT oi.name /*COLLATE*/ FROM sysobjects oi
WHERE NOT EXISTS (SELECT * FROM #tmp ti
WHERE oi.id = ti.id)
AND oi.type IN ('TR', 'P' ,'U' ,'V'))
UNION
--Added
SELECT 'added' AS ChangeType, o.name /*COLLATE*/, '' AS extra_info, 4 AS Priority
FROM sysobjects o
WHERE NOT EXISTS (SELECT * FROM #tmp t
WHERE o.id = t.id)
AND o.type IN ('TR', 'P' ,'U' ,'V')
AND o.name NOT IN ( SELECT ti.name /*COLLATE*/ FROM #tmp ti
WHERE NOT EXISTS (SELECT * FROM sysobjects oi
WHERE oi.id = ti.id))
ORDER BY Priority ASC
注:データベースのいずれかで非標準の照合順序を使用する場合/* COLLATE */
は、データベースの照合順序に置き換える必要があります。すなわちCOLLATE Latin1_General_CI_AI
私たちのアプリは複数のRDBMSで動作する必要があるため、データベース中立のトルク形式(XML)を使用して、スキーマ定義をバージョン管理に保存します。また、データベースの参照データを次のようにXML形式でバージョン管理しています(「Relationship」は参照テーブルの1つです)。
<Relationship RelationshipID="1" InternalName="Manager"/>
<Relationship RelationshipID="2" InternalName="Delegate"/>
etc.
次に、自社開発のツールを使用して、データベースのバージョンXからバージョンX + 1に移行するために必要なスキーマアップグレードスクリプトと参照データアップグレードスクリプトを生成します。
x64プラットフォームに移行した後、SQLデータベースをバージョン管理する必要があり、以前のバージョンは移行によって壊れました。SQLDMOを使用してすべてのSQLオブジェクトをフォルダーにマッピングするC#アプリケーションを作成しました。
ルート サーバー名 データベース名 スキーマオブジェクト データベーストリガー* .ddltrigger.sql 関数 ..function.sql 安全保障 役割 アプリケーションの役割 .approle.sql データベースの役割 .role.sql スキーマ* .schema.sql ユーザー .user.sql ストレージ フルテキストカタログ* .fulltext.sql ストアドプロシージャ ..proc.sql 同義語* .synonym.sql テーブル ..table.sql 制約 ... chkconst.sql ... defconst.sql インデックス ... index.sql キー ... fkey.sql ... pkey.sql ... ukey.sql トリガー ... trigger.sql タイプ ユーザー定義のデータ型 ..uddt.sql XMLスキーマコレクション* ..xmlschema.sql ビュー ..view.sql インデックス ... index.sql トリガー ... trigger.sql
次に、アプリケーションは新しく作成されたバージョンをSVNに保存されているバージョンと比較し、相違がある場合はSVNを更新します。SQLにそれほど多くの変更を加えないため、プロセスを1晩に1回実行するだけで十分であると判断しました。気になるすべてのオブジェクトへの変更を追跡できるほか、深刻な問題が発生した場合に完全なスキーマを再構築できます。
私はこのアプリを少し前に作成しました。http: //sqlschemasourcectrl.codeplex.com/は、MSFT SQL dbを好きなだけスキャンし、オブジェクト(テーブル、ビュー、プロシージャ、関数、SQL設定)をSVNに自動的にダンプします。魅力のように機能します。Unfuddleで使用します(チェックイン時にアラートを取得できます)。
Team Foundation Serverを使い始めました。データベースが中規模のサイズの場合、Visual Studioには、組み込みの比較、データ比較、データベースリファクタリングツール、データベーステストフレームワーク、さらにはデータ生成ツールとの優れたプロジェクト統合があります。
ただし、そのモデルは、非常に大規模なデータベースやサードパーティのデータベース(オブジェクトを暗号化するデータベース)にはあまり適していません。つまり、カスタマイズしたオブジェクトのみを保存することです。Visual Studio / Team Foundation Serverは、そのために非常にうまく機能します。
私はESVの回答に同意します。その理由から、データベースの更新を非常に単純なファイルで維持し、ソースコードを長く維持できるようにするために、しばらくプロジェクトを開始しました。開発者だけでなく、UATやプロダクションも簡単に更新できます。ツールはSql ServerとMySqlでのみ機能します。
いくつかのプロジェクト機能:
コードはグーグルコードでホストされています。詳細については、Googleコードを確認してください
データベース拡張プロパティファミリーのプロシージャを介して保存されたデータベースのバージョンも使用しています。私のアプリケーションには、バージョンの各ステップ用のスクリプトがあります(つまり、1.1から1.2に移動)。デプロイされると、現在のバージョンが確認され、最後のアプリバージョンに達するまでスクリプトが1つずつ実行されます。完全な「最終」バージョンを持つスクリプトはありません。クリーンなDBにデプロイしても、一連のアップグレード手順でデプロイされます。
追加したいのは、2日前にMSキャンパスで新しいVS DBエディションについてのプレゼンテーションを見たことです。プレゼンテーションは特にこのトピックに焦点が当てられていたので、私は夢中になりました。新しい機能は、T-SQLスクリプト(CREATE)でスキーマ定義を維持することに重点を置いています。T-SQLスクリプト(CREATE)は、デプロイメントスキーマを定義済みスキーマと比較し、デルタALTERを実行し、ソースコード統合と統合することにより、自動ビルドドロップ用のMSBUILD継続的統合を含みます。ドロップには、デプロイメントサイトに取得できる新しいファイルタイプ.dbschemaファイルが含まれ、コマンドラインツールは実際の「デルタ」を実行してデプロイメントを実行できます。このトピックに関するブログエントリにVSDEダウンロードへのリンクがあります。これらをチェックしてください。http://rusanu.com/2009/05/15/version-control-and-your-database/
それは非常に古い質問ですが、多くは今でもこれを解決しようとしています。彼らがしなければならないのは、Visual Studioデータベースプロジェクトについて調査することだけです。これがないと、データベース開発は非常に微妙に見えます。コードの編成からデプロイメント、バージョン管理まで、すべてを簡素化します。
私の経験では、解決策は2つあります。
開発中に複数の開発者が行う開発データベースへの変更を処理する必要があります。
お客様のサイトでデータベースのアップグレードを処理する必要があります。
#1を処理するには、強力なデータベースのdiff / mergeツールが必要です。最良のツールは、未処理の競合を手動で解決できるようにしながら、可能な限り自動マージを実行できる必要があります。
完璧なツールは、BASEデータベースと比較して、THEIRSデータベースとMINEデータベースで行われた変更を考慮に入れた3者間マージアルゴリズムを使用して、マージ操作を処理する必要があります。
SQLiteデータベースの手動マージサポートを提供する商用ツールを作成し、現在、SQLiteの3ウェイマージアルゴリズムのサポートを追加しています。それをチェックしてくださいhttp://www.sqlitecompare.comでください。
#2を処理するには、適切なアップグレードフレームワークが必要です。
基本的なアイデアは、既存のSQLスキーマから新しいSQLスキーマにアップグレードする方法を認識し、既存のすべてのDBインストールのアップグレードパスを構築できる自動アップグレードフレームワークを開発することです。
この件に関する私の記事をhttp://www.codeproject.com/KB/database/sqlite_upgrade.aspxでチェックして、私が話していることの一般的なアイデアを入手してください。
幸運を
リロン・レヴィ
DBGhost http://www.innovartis.co.uk/をチェックしてください。私は2年間、自動化された方法で使用してきました。これにより、データベースを除いて、JavaやCのビルドと同じようにDBビルドを行うことができます。私の言っていることが分かるよね。
比較ツールを使用して、データベースのバージョン管理システムを即興で作成することをお勧めします。代替案としては、xSQLスキーマ比較とxSQLデータ比較があります。
これで、データベースのスキーマのみをバージョン管理することが目標である場合は、xSQLスキーマ比較を使用してスキーマのxSQLスナップショットを生成し、これらのファイルをバージョン管理に追加できます。特定のバージョンに復帰または更新するには、データベースの現在のバージョンを宛先バージョンのスナップショットと比較するだけです。
悲しいかな、データもバージョン管理下に置きたい場合は、xSQLデータ比較を使用してデータベースの変更スクリプトを生成し、バージョン管理に.sqlファイルを追加できます。次に、これらのスクリプトを実行して、必要なバージョンに復帰/更新できます。「元に戻す」機能では、実行時にバージョン3がバージョン2と同じになる変更スクリプトを生成する必要があり、「更新」機能では、逆の変更スクリプトを生成する必要があることに注意してください。
最後に、いくつかの基本的なバッチプログラミングスキルがあれば、xSQLスキーマ比較およびxSQLデータ比較のコマンドラインバージョンを使用してプロセス全体を自動化できます。
免責事項:私はxSQLに所属しています。