私たちのデータベーススキーマの変更をバージョン管理するための適切なプロセスが整っていないので、私の店には問題があると思います。我々は多かれ少なかれカバーされているので我々は多くのバックアップをするが、このようにあなたの最後の防衛線に頼ることは悪い習慣である。
驚くべきことに、これは一般的なスレッドのようです。データベースは頻繁には変更されないので、この問題を無視するように私が話した多くのショップは、基本的には細心の注意を払うようにしています。
しかし、私はその話がどのように進むのか知っています。物事が間違って並んで何かが足りなくなるのは、時間の問題です。
これに関するベストプラクティスはありますか?あなたのために働いてきたいくつかの戦略は何ですか?
必ず読んでください データベースをバージョン管理下に置く 。 K. Scott Allenによる一連の投稿をチェックしてください。
バージョン管理に関して言えば、データベースは多くの場合2番目または3番目の市民です。私が見てきたことから、100万年の間にバージョン管理なしでコードを書くことを決して考えていなかったチーム、そして当然のことだが、どういうわけか彼らのアプリケーションが頼る重要なデータベースの周りのバージョン管理の必要性を完全に忘れている。データベースが他のコードとまったく同じ厳格なレベルのソース管理下にない場合、どのようにして自分をソフトウェアエンジニアと呼んで率直に維持できるのかわかりません。これをあなたに起こさせないでください。データベースをバージョン管理下に置きます。
データベース自体?いいえ
静的データ挿入、ストアドプロシージャなどを含むスクリプト。もちろん。それらはテキストファイルであり、プロジェクトに含まれており、他のものと同様にチェックインおよびチェックアウトされます。
もちろん理想的な世界では、あなたのデータベース管理ツールはこれをするでしょう。しかし、あなたはただそれについて懲戒されていなければなりません。
私はRails ActiveRecordの移行が大好きです。これはDMLからRubyへのスクリプトを抽象化したもので、ソースリポジトリで簡単にバージョン管理することができます。
しかし、少し作業をすれば、同じことを実行できます。 DDLの変更(ALTER TABLEなど)はテキストファイルに保存できます。ファイル名には番号付けシステム(または日付スタンプ)を付けて、順番に適用してください。
Railsはまた、DB内に最後に適用された移行を追跡する「バージョン」テーブルを持っています。あなたは同じことを簡単にすることができます。
ソース管理を使用してデータベースの変更を管理するには、 LiquiBase をご覧ください。
本番データベースを変更するために単にログインして "ALTER TABLE"コマンドを入力し始めないでください。私が行っているプロジェクトはすべての顧客サイトにデータベースがあるので、データベースへのすべての変更は2つの場所、新しい顧客サイトに新しいデータベースを作成するために使用されるダンプファイル、および実行される更新ファイルで行われます現在のデータベースのバージョン番号をファイル内の最大の番号と照合し、データベースを適切な場所に更新します。だから、例えば、最後の2、3のアップデート:
if [ $VERSION \< '8.0.108' ] ; then
psql -U cosuser $dbName << EOF8.0.108
BEGIN TRANSACTION;
--
-- Remove foreign key that shouldn't have been there.
-- PCR:35665
--
ALTER TABLE migratorjobitems
DROP CONSTRAINT migratorjobitems_destcmaid_fkey;
--
-- Increment the version
UPDATE sys_info
SET value = '8.0.108'
WHERE key = 'DB VERSION';
END TRANSACTION;
EOF8.0.108
fi
if [ $VERSION \< '8.0.109' ] ; then
psql -U cosuser $dbName << EOF8.0.109
BEGIN TRANSACTION;
--
-- I missed a couple of cases when I changed the legacy playlist
-- from reporting showplaylistidnum to playlistidnum
--
ALTER TABLE featureidrequestkdcs
DROP CONSTRAINT featureidrequestkdcs_cosfeatureid_fkey;
ALTER TABLE featureidrequestkdcs
ADD CONSTRAINT featureidrequestkdcs_cosfeatureid_fkey
FOREIGN KEY (cosfeatureid)
REFERENCES playlist(playlistidnum)
ON DELETE CASCADE;
--
ALTER TABLE ticket_system_ids
DROP CONSTRAINT ticket_system_ids_showplaylistidnum_fkey;
ALTER TABLE ticket_system_ids
RENAME showplaylistidnum
TO playlistidnum;
ALTER TABLE ticket_system_ids
ADD CONSTRAINT ticket_system_ids_playlistidnum_fkey
FOREIGN KEY (playlistidnum)
REFERENCES playlist(playlistidnum)
ON DELETE CASCADE;
--
-- Increment the version
UPDATE sys_info
SET value = '8.0.109'
WHERE key = 'DB VERSION';
END TRANSACTION;
EOF8.0.109
fi
私はこれを実行するためのより良い方法があると確信していますが、それは今のところ私にとってはうまくいきました。
はい。コードはコードです。私の経験則では、開発用のマシンや本番用のマシンを見ずに、アプリケーションを最初からビルドしてデプロイすることができる _が必要です。
私が見たベストプラクティスは、ステージングサーバー上でデータベースをスクラップして再構築するためのビルドスクリプトを作成することです。各反復はデータベース変更のためのフォルダを与えられ、すべての変更は "Drop ... Create"でスクリプト化されました。このようにして、バージョンアップしたいフォルダへのビルドを指定することによって、いつでも以前のバージョンにロールバックすることができます。
これはNaNt/CruiseControlで行われたと思います。
はい、データベースをバージョン管理することが重要だと思います。データではなく、確かにスキーマです。
Ruby on Railsでは、これは「マイグレーション」を伴うフレームワークによって処理されます。データベースを変更するときはいつでも、その変更を適用するスクリプトを作成し、それをソース管理にチェックインします。
私の店はそのアイデアをとても気に入っていたので、私たちのJavaベースのビルド シェルスクリプトを使った とAntに機能を追加しました。このプロセスを私たちの展開ルーチンに統合しました。すぐに使えるDBバージョン管理をサポートしていない他のフレームワークで同じことをするスクリプトを書くのはかなり簡単でしょう。
Visual Studioの新しいデータベースプロジェクトは、ソース管理と変更スクリプトを提供します。
データベースを比較し、一方のスキーマを他方のスキーマに変換したり、一方のスキーマのデータを他方のスキーマと一致するように更新したりするスクリプトを生成できます。
Dbスキーマは、DBを記述するDDLコマンドごとに1つずつ、多数の多数の小さな.sqlファイルを作成するために「細断処理」されています。
+トム
追加情報2008-11-30
私はこの1年の間開発者としてそれを使っていて、本当にそれが好きです。私の開発作業と本番環境を比較し、そのリリースに使用するスクリプトを生成するのは簡単です。 DBAが「エンタープライズタイプ」のプロジェクトに必要とする機能が欠けているかどうかはわかりません。
スキーマはSQLファイルに「細断処理」されているため、ソース管理は正常に機能します。
1つの落とし穴は、dbプロジェクトを使用するときには異なる考え方を持つ必要があるということです。このツールにはVSの "dbプロジェクト"があります。これは単なるsqlであり、スキーマとその他の管理データを持つ自動的に生成されたローカルデータベースです。ただし、アプリケーションデータはなく、使用するローカル開発データベースアプリデータ開発作業。あなたはめったに自動的に生成されたdbに気づいていません、しかしあなたはそれをそのままにしておくことができるようにそこにそれを知っている必要があります:)。この特別なdbは、名前にGuidがあるので、はっきりと認識できます。
VS DBプロジェクトは、他のチームメンバーがあなたのローカルプロジェクト/関連するdbに加えたdbの変更を統合するという素晴らしい仕事をします。しかし、プロジェクトスキーマとローカルのdev dbスキーマを比較してmodを適用するには、追加の手順を実行する必要があります。それは理にかなっていますが、最初は厄介です。
DBプロジェクトは非常に強力なツールです。スクリプトを生成するだけでなく、すぐに適用することもできます。プロダクションデータベースを破壊しないように注意してください。 ;)
私はVS DBプロジェクトがとても好きで、今後のすべてのdbプロジェクトにこのツールを使うことを期待しています。
+トム
開発チームにSQLデータベースのソース管理システムを使用するよう要求することは、問題が発生するのを防ぐための魔法の弾丸ではありません。開発者がオブジェクトに加えた変更を別のSQLスクリプトに保存し、ソース管理システムクライアントを開き、そのクライアントを使用してSQLスクリプトファイルをチェックインしてから、データベースソース管理を実行すると、オーバーヘッドが発生します。変更をライブデータベースに適用します。
ApexSQL Source Control というSSMSアドインを使用することをお勧めします。 SSMSから直接ウィザードを使用して、開発者はデータベースオブジェクトをソース管理システムに簡単にマッピングできます。このアドインには、TFS、Git、Subversion、およびその他のSCシステムのサポートが含まれています。静的データのソース管理のサポートも含まれています。
ApexSQLソース管理をダウンロードしてインストールした後、バージョン管理するデータベースを右クリックしてSSMSのApexSQLソース管理サブメニューに移動します。 [データベースをソース管理にリンク]オプションをクリックし、ソース管理システムと開発モデルを選択します。その後、ログイン情報と選択したソース管理システムのリポジトリ文字列を入力する必要があります。
あなたはより多くの情報のためにこの記事を読むことができます: http://solutioncenter.apexsql.com/sql-source-control-reduce-database-development-time/
データベースで作成されたすべてのオブジェクトをソース管理します。開発者が正直に言うと(ソース管理にいなくてもオブジェクトを作成できるため)、データベース管理者は定期的にソース管理にないものを探し、見つけた場合は問題ないかどうかを尋ねずに削除します。
作成/更新スクリプトと、サンプルデータを生成するスクリプトを保存することで行います。
はい、私たちのビルドの一部として私たちのSQLを保持することによってそれを行います - 私たちはDROP.sql、CREATE.sql、USERS.sql、VALUES.sqlおよびそれらをバージョン管理するので、タグ付けされたバージョンに戻すことができます。
必要なときにいつでもdbを再作成できるantタスクもあります。
さらに、SQLはそれに付随するソースコードとともにタグ付けされます。
私が今までプロジェクトで使用した中で最も成功した方式は、バックアップと差分SQLファイルを組み合わせたものです。基本的に、各リリースの後にデータベースのバックアップを取り、SQLダンプを作成して、必要に応じて最初から空のスキーマを作成できるようにします。その後、DBを変更する必要があるときはいつでも、バージョン管理下のsqlディレクトリにalter scripを追加します。最初の変更は01_add_created_on_column.sqlのようなものになり、次のスクリプトは02_added_customers_indexになります。私たちのCIマシンはこれらをチェックし、バックアップから復元されたdbの新しいコピーでそれらを順番に実行します。
また、devsがローカルDBを現在のバージョンに単一のコマンドで再初期化するために使用できるスクリプトも用意されています。
データベーススキーマの変更をすべてバージョン管理するには、 SchemaBank を使用します。
私たちのチームルールは、設計作業を最初に格納することなく、決してdbサーバーに直接触れないことです。しかし、都合のよいことに、誰かがルールを破ることに誘惑されるかもしれません。スキーマダンプをもう一度スキーマバンクにインポートし、相違を検出して不一致が見つかった場合は誰かに攻撃を任せます。データベースとスキーマの設計を同期させるために、そこから変更スクリプトを生成することはできますが、それは嫌いです。
ちなみに、それらはまた、私がステージング用とプロダクション用に維持できるように、バージョン管理ツリー内にブランチを作成することも可能にします。サンドボックスをコーディングするためのもの。
バージョン管理と変更管理を備えた、非常にきちんとしたWebベースのスキーマ設計ツール。
私はMySQL WorkbechからエクスポートされたSQL CREATEスクリプトを使い、それからそれらの "Export SQL ALTER"機能を使って一連のcreateスクリプト(もちろん番号付き)とそれらの間で変更を適用することができるalterスクリプトになります。
3.- SQL ALTERスクリプトのエクスポート通常、モデルに加えた変更を反映して、今すぐALTER TABLEステートメントを手で書く必要があります。しかし、あなたは頭が良くてWorkbenchにあなたのために大変な仕事をさせることができます。メインメニューから「ファイル」 - >「エクスポート」 - >「フォワードエンジニアSQL ALTERスクリプト…」を選択するだけです。
現在のモデルと比較する必要があるSQL CREATEファイルを指定するように促されます。
ステップ1からSQL CREATEスクリプトを選択します。その後、ツールはALTER TABLEスクリプトを自動的に生成します。このスクリプトをデータベースに対して実行して、最新の状態にすることができます。
これはMySQL Query Browserまたはmysql client.Voilaを使用して実行できます。モデルとデータベースが同期されました。
出典: MySQL Workbench Community Edition:スキーマ同期ガイド
もちろん、このスクリプトはすべてバージョン管理下にあります。
データベースがSQL Serverの場合、私たちはあなたが探しているソリューションだけを持っているかもしれません。 SQL Source Control 1.0がリリースされました。
http://www.red-gate.com/products/SQL_Source_Control/index.htm
これはSSMSに統合され、データベースオブジェクトとVCSの間に接着剤を提供します。 「スクリプトアウト」は透過的に行われ(内部的にはSQL Compareエンジンを使用します)、使用するのが非常に簡単になるため、開発者はこのプロセスを採用することをお勧めしません。
別のVisual Studioソリューションは ReadyRoll で、これはSSDTデータベースプロジェクトのサブタイプとして実装されています。これはマイグレーション主導のアプローチを取り、DevOpsチームの自動化要件により適しています。
データベースモデル自体については多くの議論がありましたが、必要なデータも.SQLファイルに保存しています。
例えば、有用であるためには、あなたのアプリケーションはインストールでこれを必要とするかもしれません:
INSERT INTO Currency (CurrencyCode, CurrencyName)
VALUES ('AUD', 'Australian Dollars');
INSERT INTO Currency (CurrencyCode, CurrencyName)
VALUES ('USD', 'US Dollars');
Subversionの下にcurrency.sql
というファイルがあります。ビルドプロセスの手動ステップとして、以前のcurrency.sqlと最新のものを比較し、アップグレードスクリプトを作成します。
はい、いつも。必要に応じて、有用な一連のサンプルデータを使用して運用データベース構造を再作成できるはずです。そうでなければ、時間をかけて物事を実行し続けるためのマイナーな変更は忘れられてしまい、その後あなたは噛まれ、大きな時間を過ごします。あなたがあなたが必要とは思わないかもしれないけれどもあなたがそれをする日それが10倍以上の価格の価値があるその保険!
私は自分のデータベースをベアメタルから再作成するのに必要なものをすべて持っています。やり方はたくさんあると思いますが、私のスクリプトなどはすべてSubversionに格納されているので、Subversionからそれらをすべて削除してインストーラを実行することでDB構造などを再構築できます。
データベースを取り巻くすべてのものをバージョン管理し、ソース管理します。
これらすべてを、Change Managerといくつかのカスタムスクリプトを使用した自動ジョブで行います。変更マネージャはこれらの変更を監視し、いつ変更が行われたかを通知します。
私は通常、すべての変更に対してSQLスクリプトを作成し、もう1つはそれらの変更を元に戻し、それらのスクリプトをバージョン管理下に置くようにします。
それから、新しいデータベースをオンデマンドで作成する手段があり、簡単にリビジョン間を移動できます。私たちがリリースするたびに、私たちはスクリプトをひとまとめにします(手作業になりますが、実際にはほとんどありませんhard)、バージョン間で変換できるスクリプトのセットもあります。
はい、あなたがそれを言う前に、これはRailsと他のものがするものと非常に似ています、しかしそれはかなりうまくいくように思われるので、私は恥知らずに考えを持ち上げたことを認めて問題ありません:)
すべてのDBはソース管理下に置かれるべきであり、開発者は自分のローカルデータベースを一から作成する簡単な方法を持つべきだと思います。データベース専門家のためのVisual Studioに触発されて、私はMS SQLデータベースをスクリプト化し、そしてあなたのローカルDBエンジンにそれらを展開する簡単な方法を提供するオープンソースツールを作成しました。試してください http://dbsourcetools.codeplex.com/ 。楽しんでください、 - ネイサン。
これは、SQL Server 2005/2008データベース上の(DDLステートメントを介した)dbオブジェクトに対する変更の追跡を実装するトリガーに対する貧乏人の解決策のサンプルです。データベース上で実行された各sqlコマンドのソースコードで必須のsomeValue xmlタグの使用を強制する方法の簡単なサンプルも含まれています。コードはかなり長いです - それは空のデータベースを作成します+必要なトラッキングテーブル構造+必要なdb関数と移入トリガーすべてが[ga]スキーマの下で走っています。
USE [master]
GO
/****** Object: Database [DBGA_DEV] Script Date: 04/22/2009 13:22:01 ******/
CREATE DATABASE [DBGA_DEV] ON PRIMARY
( NAME = N'DBGA_DEV', FILENAME = N'D:\GENAPP\DATA\DBFILES\DBGA_DEV.mdf' , SIZE = 3072KB , MAXSIZE = UNLIMITED, FILEGROWTH = 1024KB )
LOG ON
( NAME = N'DBGA_DEV_log', FILENAME = N'D:\GENAPP\DATA\DBFILES\DBGA_DEV_log.ldf' , SIZE = 6208KB , MAXSIZE = 2048GB , FILEGROWTH = 10%)
GO
ALTER DATABASE [DBGA_DEV] SET COMPATIBILITY_LEVEL = 100
GO
IF (1 = FULLTEXTSERVICEPROPERTY('IsFullTextInstalled'))
begin
EXEC [DBGA_DEV].[dbo].[sp_fulltext_database] @action = 'enable'
end
GO
ALTER DATABASE [DBGA_DEV] SET ANSI_NULL_DEFAULT OFF
GO
ALTER DATABASE [DBGA_DEV] SET ANSI_NULLS OFF
GO
ALTER DATABASE [DBGA_DEV] SET ANSI_PADDING ON
GO
ALTER DATABASE [DBGA_DEV] SET ANSI_WARNINGS OFF
GO
ALTER DATABASE [DBGA_DEV] SET ARITHABORT OFF
GO
ALTER DATABASE [DBGA_DEV] SET AUTO_CLOSE OFF
GO
ALTER DATABASE [DBGA_DEV] SET AUTO_CREATE_STATISTICS ON
GO
ALTER DATABASE [DBGA_DEV] SET AUTO_SHRINK OFF
GO
ALTER DATABASE [DBGA_DEV] SET AUTO_UPDATE_STATISTICS ON
GO
ALTER DATABASE [DBGA_DEV] SET CURSOR_CLOSE_ON_COMMIT OFF
GO
ALTER DATABASE [DBGA_DEV] SET CURSOR_DEFAULT GLOBAL
GO
ALTER DATABASE [DBGA_DEV] SET CONCAT_NULL_YIELDS_NULL OFF
GO
ALTER DATABASE [DBGA_DEV] SET NUMERIC_ROUNDABORT OFF
GO
ALTER DATABASE [DBGA_DEV] SET QUOTED_IDENTIFIER OFF
GO
ALTER DATABASE [DBGA_DEV] SET RECURSIVE_TRIGGERS OFF
GO
ALTER DATABASE [DBGA_DEV] SET DISABLE_BROKER
GO
ALTER DATABASE [DBGA_DEV] SET AUTO_UPDATE_STATISTICS_ASYNC OFF
GO
ALTER DATABASE [DBGA_DEV] SET DATE_CORRELATION_OPTIMIZATION OFF
GO
ALTER DATABASE [DBGA_DEV] SET TRUSTWORTHY OFF
GO
ALTER DATABASE [DBGA_DEV] SET ALLOW_SNAPSHOT_ISOLATION OFF
GO
ALTER DATABASE [DBGA_DEV] SET PARAMETERIZATION SIMPLE
GO
ALTER DATABASE [DBGA_DEV] SET READ_COMMITTED_SNAPSHOT OFF
GO
ALTER DATABASE [DBGA_DEV] SET HONOR_BROKER_PRIORITY OFF
GO
ALTER DATABASE [DBGA_DEV] SET READ_WRITE
GO
ALTER DATABASE [DBGA_DEV] SET RECOVERY FULL
GO
ALTER DATABASE [DBGA_DEV] SET MULTI_USER
GO
ALTER DATABASE [DBGA_DEV] SET PAGE_VERIFY CHECKSUM
GO
ALTER DATABASE [DBGA_DEV] SET DB_CHAINING OFF
GO
EXEC [DBGA_DEV].sys.sp_addextendedproperty @name=N'DbType', @value=N'DEV'
GO
EXEC [DBGA_DEV].sys.sp_addextendedproperty @name=N'DbVersion', @value=N'0.0.1.20090414.1100'
GO
USE [DBGA_DEV]
GO
/****** Object: Schema [ga] Script Date: 04/22/2009 13:21:29 ******/
CREATE SCHEMA [ga] AUTHORIZATION [dbo]
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'Contains the objects of the Generic Application database' , @level0type=N'SCHEMA',@level0name=N'ga'
GO
/****** Object: Table [ga].[tb_DataMeta_ObjChangeLog] Script Date: 04/22/2009 13:21:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [ga].[tb_DataMeta_ObjChangeLog](
[LogId] [int] IDENTITY(1,1) NOT NULL,
[TimeStamp] [timestamp] NOT NULL,
[DatabaseName] [varchar](256) NOT NULL,
[SchemaName] [varchar](256) NOT NULL,
[DbVersion] [varchar](20) NOT NULL,
[DbType] [varchar](20) NOT NULL,
[EventType] [varchar](50) NOT NULL,
[ObjectName] [varchar](256) NOT NULL,
[ObjectType] [varchar](25) NOT NULL,
[Version] [varchar](50) NULL,
[SqlCommand] [varchar](max) NOT NULL,
[EventDate] [datetime] NOT NULL,
[LoginName] [varchar](256) NOT NULL,
[FirstName] [varchar](256) NULL,
[LastName] [varchar](50) NULL,
[ChangeDescription] [varchar](1000) NULL,
[Description] [varchar](1000) NULL,
[ObjVersion] [varchar](20) NOT NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The database version as written in the extended prop of the database' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'TABLE',@level1name=N'tb_DataMeta_ObjChangeLog', @level2type=N'COLUMN',@level2name=N'DbVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'dev , test , qa , fb or prod' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'TABLE',@level1name=N'tb_DataMeta_ObjChangeLog', @level2type=N'COLUMN',@level2name=N'DbType'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'The name of the object as it is registered in the sys.objects ' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'TABLE',@level1name=N'tb_DataMeta_ObjChangeLog', @level2type=N'COLUMN',@level2name=N'ObjectName'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'TABLE',@level1name=N'tb_DataMeta_ObjChangeLog', @level2type=N'COLUMN',@level2name=N'Description'
GO
SET IDENTITY_INSERT [ga].[tb_DataMeta_ObjChangeLog] ON
INSERT [ga].[tb_DataMeta_ObjChangeLog] ([LogId], [DatabaseName], [SchemaName], [DbVersion], [DbType], [EventType], [ObjectName], [ObjectType], [Version], [SqlCommand], [EventDate], [LoginName], [FirstName], [LastName], [ChangeDescription], [Description], [ObjVersion]) VALUES (3, N'DBGA_DEV', N'en', N'0.0.1.20090414.1100', N'DEV', N'DROP_TABLE', N'tb_BL_Products', N'TABLE', N' some', N'<EVENT_INSTANCE><EventType>DROP_TABLE</EventType><PostTime>2009-04-22T11:03:11.880</PostTime><SPID>57</SPID><ServerName>YSG</ServerName><LoginName>ysg\yordgeor</LoginName><UserName>dbo</UserName><DatabaseName>DBGA_DEV</DatabaseName><SchemaName>en</SchemaName><ObjectName>tb_BL_Products</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE"/><CommandText>drop TABLE [en].[tb_BL_Products] --<Version> some</Version>
</CommandText></TSQLCommand></EVENT_INSTANCE>', CAST(0x00009BF300B6271C AS DateTime), N'ysg\yordgeor', N'Yordan', N'Georgiev', NULL, NULL, N'0.0.0')
INSERT [ga].[tb_DataMeta_ObjChangeLog] ([LogId], [DatabaseName], [SchemaName], [DbVersion], [DbType], [EventType], [ObjectName], [ObjectType], [Version], [SqlCommand], [EventDate], [LoginName], [FirstName], [LastName], [ChangeDescription], [Description], [ObjVersion]) VALUES (4, N'DBGA_DEV', N'en', N'0.0.1.20090414.1100', N'DEV', N'CREATE_TABLE', N'tb_BL_Products', N'TABLE', N' 2.2.2 ', N'<EVENT_INSTANCE><EventType>CREATE_TABLE</EventType><PostTime>2009-04-22T11:03:18.620</PostTime><SPID>57</SPID><ServerName>YSG</ServerName><LoginName>ysg\yordgeor</LoginName><UserName>dbo</UserName><DatabaseName>DBGA_DEV</DatabaseName><SchemaName>en</SchemaName><ObjectName>tb_BL_Products</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE"/><CommandText>CREATE TABLE [en].[tb_BL_Products](
[ProducId] [int] NULL,
[ProductName] [nchar](10) NULL,
[ProductDescription] [varchar](5000) NULL
) ON [PRIMARY]
/*
<Version> 2.2.2 </Version>

*/
</CommandText></TSQLCommand></EVENT_INSTANCE>', CAST(0x00009BF300B62F07 AS DateTime), N'ysg\yordgeor', N'Yordan', N'Georgiev', NULL, NULL, N'0.0.0')
INSERT [ga].[tb_DataMeta_ObjChangeLog] ([LogId], [DatabaseName], [SchemaName], [DbVersion], [DbType], [EventType], [ObjectName], [ObjectType], [Version], [SqlCommand], [EventDate], [LoginName], [FirstName], [LastName], [ChangeDescription], [Description], [ObjVersion]) VALUES (5, N'DBGA_DEV', N'en', N'0.0.1.20090414.1100', N'DEV', N'DROP_TABLE', N'tb_BL_Products', N'TABLE', N' 2.2.2 ', N'<EVENT_INSTANCE><EventType>DROP_TABLE</EventType><PostTime>2009-04-22T11:25:12.620</PostTime><SPID>57</SPID><ServerName>YSG</ServerName><LoginName>ysg\yordgeor</LoginName><UserName>dbo</UserName><DatabaseName>DBGA_DEV</DatabaseName><SchemaName>en</SchemaName><ObjectName>tb_BL_Products</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE"/><CommandText>drop TABLE [en].[tb_BL_Products] 
</CommandText></TSQLCommand></EVENT_INSTANCE>', CAST(0x00009BF300BC32F1 AS DateTime), N'ysg\yordgeor', N'Yordan', N'Georgiev', NULL, NULL, N'0.0.0')
INSERT [ga].[tb_DataMeta_ObjChangeLog] ([LogId], [DatabaseName], [SchemaName], [DbVersion], [DbType], [EventType], [ObjectName], [ObjectType], [Version], [SqlCommand], [EventDate], [LoginName], [FirstName], [LastName], [ChangeDescription], [Description], [ObjVersion]) VALUES (6, N'DBGA_DEV', N'en', N'0.0.1.20090414.1100', N'DEV', N'CREATE_TABLE', N'tb_BL_Products', N'TABLE', N' 2.2.2 ', N'<EVENT_INSTANCE><EventType>CREATE_TABLE</EventType><PostTime>2009-04-22T11:25:19.053</PostTime><SPID>57</SPID><ServerName>YSG</ServerName><LoginName>ysg\yordgeor</LoginName><UserName>dbo</UserName><DatabaseName>DBGA_DEV</DatabaseName><SchemaName>en</SchemaName><ObjectName>tb_BL_Products</ObjectName><ObjectType>TABLE</ObjectType><TSQLCommand><SetOptions ANSI_NULLS="ON" ANSI_NULL_DEFAULT="ON" ANSI_PADDING="ON" QUOTED_IDENTIFIER="ON" ENCRYPTED="FALSE"/><CommandText>CREATE TABLE [en].[tb_BL_Products](
[ProducId] [int] NULL,
[ProductName] [nchar](10) NULL,
[ProductDescription] [varchar](5000) NULL
) ON [PRIMARY]
/*
<Version> 2.2.2 </Version>

*/
</CommandText></TSQLCommand></EVENT_INSTANCE>', CAST(0x00009BF300BC3A69 AS DateTime), N'ysg\yordgeor', N'Yordan', N'Georgiev', NULL, NULL, N'0.0.0')
SET IDENTITY_INSERT [ga].[tb_DataMeta_ObjChangeLog] OFF
/****** Object: Table [ga].[tb_BLSec_LoginsForUsers] Script Date: 04/22/2009 13:21:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [ga].[tb_BLSec_LoginsForUsers](
[LoginsForUsersId] [int] IDENTITY(1,1) NOT NULL,
[LoginName] [nvarchar](100) NOT NULL,
[FirstName] [varchar](100) NOT NULL,
[SecondName] [varchar](100) NULL,
[LastName] [varchar](100) NOT NULL,
[DomainName] [varchar](100) NOT NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
SET IDENTITY_INSERT [ga].[tb_BLSec_LoginsForUsers] ON
INSERT [ga].[tb_BLSec_LoginsForUsers] ([LoginsForUsersId], [LoginName], [FirstName], [SecondName], [LastName], [DomainName]) VALUES (1, N'ysg\yordgeor', N'Yordan', N'Stanchev', N'Georgiev', N'yordgeor')
SET IDENTITY_INSERT [ga].[tb_BLSec_LoginsForUsers] OFF
/****** Object: Table [en].[tb_BL_Products] Script Date: 04/22/2009 13:21:40 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [en].[tb_BL_Products](
[ProducId] [int] NULL,
[ProductName] [nchar](10) NULL,
[ProductDescription] [varchar](5000) NULL
) ON [PRIMARY]
GO
SET ANSI_PADDING ON
GO
/****** Object: StoredProcedure [ga].[procUtils_SqlCheatSheet] Script Date: 04/22/2009 13:21:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE PROCEDURE [ga].[procUtils_SqlCheatSheet]
as
set nocount on
--what was the name of the table with something like role
/*
SELECT * from sys.tables where [name] like '%POC%'
*/
-- what are the columns of this table
/*
select column_name , DATA_TYPE , CHARACTER_MAXIMUM_LENGTH, table_name from Information_schema.columns where table_name='tbGui_ExecutePOC'
*/
-- find proc
--what was the name of procedure with something like role
/*
select * from sys.procedures where [name] like '%ext%'
exec sp_HelpText procName
*/
/*
exec sp_helpText procUtils_InsertGenerator
*/
--how to list all databases in sql server
/*
SELECT database_id AS ID, NULL AS ParentID, name AS Text FROM sys.databases ORDER BY [name]
*/
--HOW-TO LIST ALL TABLES IN A SQL SERVER 2005 DATABASE
/*
SELECT TABLE_NAME FROM [POC].INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE'
AND TABLE_NAME <> 'dtproperties'
ORDER BY TABLE_NAME
*/
--HOW-TO ENABLE XP_CMDSHELL START
-------------------------------------------------------------------------
-- configure verbose mode temporarily
-- EXECUTE sp_configure 'show advanced options', 1
-- RECONFIGURE WITH OVERRIDE
--GO
--ENABLE xp_cmdshell
-- EXECUTE sp_configure 'xp_cmdshell', '1'
-- RECONFIGURE WITH OVERRIDE
-- EXEC SP_CONFIGURE 'show advanced option', '1';
-- SHOW THE CONFIGURATION
-- EXEC SP_CONFIGURE;
--turn show advance options off
-- GO
--EXECUTE sp_configure 'show advanced options', 0
-- RECONFIGURE WITH OVERRIDE
-- GO
--HOW-TO ENABLE XP_CMDSHELL END
-------------------------------------------------------------------------
--HOW-TO IMPLEMENT SLEEP
-- sleep for 10 seconds
-- WAITFOR DELAY '00:00:10' SELECT * FROM My_Table
/* LIST ALL PRIMARY KEYS
SELECT
INFORMATION_SCHEMA.TABLE_CONSTRAINTS.TABLE_NAME AS TABLE_NAME,
INFORMATION_SCHEMA.KEY_COLUMN_USAGE.COLUMN_NAME AS COLUMN_NAME,
REPLACE(INFORMATION_SCHEMA.TABLE_CONSTRAINTS.CONSTRAINT_TYPE,' ', '_') AS CONSTRAINT_TYPE
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE ON
INFORMATION_SCHEMA.TABLE_CONSTRAINTS.CONSTRAINT_NAME =
INFORMATION_SCHEMA.KEY_COLUMN_USAGE.CONSTRAINT_NAME
WHERE
INFORMATION_SCHEMA.TABLE_CONSTRAINTS.TABLE_NAME <> N'sysdiagrams'
ORDER BY
INFORMATION_SCHEMA.TABLE_CONSTRAINTS.TABLE_NAME ASC
*/
--HOW-TO COPY TABLE AND THE WHOLE TABLE DATA , COPY TABLE FROM DB TO DB
--==================================================START
/*
use Poc_Dev
go
drop table tbGui_LinksVisibility
use POc_test
go
select *
INTO [POC_Dev].[ga].[tbGui_LinksVisibility]
from [POC_TEST].[ga].[tbGui_LinksVisibility]
*/
--HOW-TO COPY TABLE AND THE WHOLE TABLE DATA , COPY TABLE FROM DB TO DB
--====================================================END
--=================================================== SEE TABLE METADATA START
/*
SELECT c.name AS [COLUMN_NAME], sc.data_type AS [DATA_TYPE], [value] AS
[DESCRIPTION] , c.max_length as [MAX_LENGTH] , c.is_nullable AS [OPTIONAL]
, c.is_identity AS [IS_PRIMARY_KEY] FROM sys.extended_properties AS ep
INNER JOIN sys.tables AS t ON ep.major_id = t.object_id
INNER JOIN sys.columns AS c ON ep.major_id = c.object_id AND ep.minor_id
= c.column_id
INNER JOIN INFORMATION_SCHEMA.COLUMNS sc ON t.name = sc.table_name and
c.name = sc.column_name
WHERE class = 1 and t.name = 'tbGui_ExecutePOC' ORDER BY SC.DATA_TYPE
*/
--=================================================== SEE TABLE METADATA END
/*
select * from Information_schema.columns
select table_name , column_name from Information_schema.columns where table_name='tbGui_Wizards'
*/
--=================================================== LIST ALL TABLES AND THEIR DESCRIPTOINS START
/*
SELECT T.name AS TableName, CAST(Props.value AS varchar(1000)) AS
TableDescription
FROM sys.tables AS T LEFT OUTER JOIN
(SELECT class, class_desc, major_id, minor_id,
name, value
FROM sys.extended_properties
WHERE (minor_id = 0) AND (class = 1)) AS
Props ON T.object_id = Props.major_id
WHERE (T.type = 'U') AND (T.name <> N'sysdiagrams')
ORDER BY TableName
*/
--=================================================== LIST ALL TABLES AND THEIR DESCRIPTOINS START
--=================================================== LIST ALL OBJECTS FROM DB START
/*
use DB
--HOW-TO LIST ALL PROCEDURE IN A DATABASE
select s.name from sysobjects s where type = 'P'
--HOW-TO LIST ALL TRIGGERS BY NAME IN A DATABASE
select s.name from sysobjects s where type = 'TR'
--HOW-TO LIST TABLES IN A DATABASE
select s.name from sysobjects s where type = 'U'
--how-to list all system tables in a database
select s.name from sysobjects s where type = 's'
--how-to list all the views in a database
select s.name from sysobjects s where type = 'v'
*/
/*
Similarly you can find out other objects created by user, simple change type =
C = CHECK constraint
D = Default or DEFAULT constraint
F = FOREIGN KEY constraint
L = Log
FN = Scalar function
IF = In-lined table-function
P = Stored procedure
PK = PRIMARY KEY constraint (type is K)
RF = Replication filter stored procedure
S = System table
TF = Table function
TR = Trigger
U = User table ( this is the one I discussed above in the example)
UQ = UNIQUE constraint (type is K)
V = View
X = Extended stored procedure
*/
--=================================================== HOW-TO SEE ALL MY PERMISSIONS START
/*
SELECT * FROM fn_my_permissions(NULL, 'SERVER');
USE poc_qa;
SELECT * FROM fn_my_permissions (NULL, 'database');
GO
*/
--=================================================== HOW-TO SEE ALL MY PERMISSIONS END
/*
--find table
use poc_dev
go
select s.name from sysobjects s where type = 'u' and s.name like '%Visibility%'
select * from tbGui_LinksVisibility
*/
/* find cursor
use poc
go
DECLARE @procName varchar(100)
DECLARE @cursorProcNames CURSOR
SET @cursorProcNames = CURSOR FOR
select name from sys.procedures where modify_date > '2009-02-05 13:12:15.273' order by modify_date desc
OPEN @cursorProcNames
FETCH NEXT
FROM @cursorProcNames INTO @procName
WHILE @@FETCH_STATUS = 0
BEGIN
set nocount off;
exec sp_HelpText @procName --- or print them
-- print @procName
FETCH NEXT
FROM @cursorProcNames INTO @procName
END
CLOSE @cursorProcNames
select @@error
*/
/* -- SEE STORED PROCEDURE EXT PROPS
SELECT ep.name as 'EXT_PROP_NAME' , SP.NAME , [value] as 'DESCRIPTION' FROM sys.extended_properties as ep left join sys.procedures as sp on sp.object_id = ep.major_id where sp.type='P'
-- what the hell I ve been doing lately on sql server 2005 / 2008
select o.name ,
(SELECT [definition] AS [text()] FROM sys.all_sql_modules where sys.all_sql_modules.object_id=a.object_id FOR XML PATH(''), TYPE) AS Statement_Text
, a.object_id, o.modify_date from sys.all_sql_modules a left join sys.objects o on a.object_id=o.object_id order by 4 desc
-- GET THE RIGHT LANG SCHEMA START
DECLARE @template AS varchar(max)
SET @template = 'SELECT * FROM {object_name}'
DECLARE @object_name AS sysname
SELECT @object_name = QUOTENAME(s.name) + '.' + QUOTENAME(o.name)
FROM sys.objects o
INNER JOIN sys.schemas s
ON s.schema_id = o.schema_id
WHERE o.object_id = OBJECT_ID(QUOTENAME(@LANG) + '.[TestingLanguagesInNameSpacesDelMe]')
IF @object_name IS NOT NULL
BEGIN
DECLARE @sql AS varchar(max)
SET @sql = REPLACE(@template, '{object_name}', @object_name)
EXEC (@sql)
END
-- GET THE RIGHT LANG SCHEMA END
-- SEE STORED PROCEDURE EXT PROPS end*/
set nocount off
GO
EXEC sys.sp_addextendedproperty @name=N'AuthorName', @value=N'Yordan Georgiev' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'PROCEDURE',@level1name=N'procUtils_SqlCheatSheet'
GO
EXEC sys.sp_addextendedproperty @name=N'ProcDescription', @value=N'TODO:ADD HERE DESCRPIPTION' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'PROCEDURE',@level1name=N'procUtils_SqlCheatSheet'
GO
EXEC sys.sp_addextendedproperty @name=N'ProcVersion', @value=N'0.1.0.20090406.1317' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'PROCEDURE',@level1name=N'procUtils_SqlCheatSheet'
GO
/****** Object: UserDefinedFunction [ga].[GetDbVersion] Script Date: 04/22/2009 13:21:42 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [ga].[GetDbVersion]()
RETURNS VARCHAR(20)
BEGIN
RETURN convert(varchar(20) , (select value from sys.extended_properties where name='DbVersion' and class_desc='DATABASE') )
END
GO
EXEC sys.sp_addextendedproperty @name=N'AuthorName', @value=N'Yordan Georgiev' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'FUNCTION',@level1name=N'GetDbVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'ChangeDescription', @value=N'Initial creation' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'FUNCTION',@level1name=N'GetDbVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'CreatedWhen', @value=N'getDate()' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'FUNCTION',@level1name=N'GetDbVersion'
GO
EXEC sys.sp_addextendedproperty @name=N'Description', @value=N'Gets the current version of the database ' , @level0type=N'SCHEMA',@level0name=N'ga', @level1type=N'FUNCTION',@level1name=N'GetDbVersion'
GO
/****** Object: UserDefinedFunction [ga].[GetDbType] Script Date: 04/22/2009 13:21:42 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [ga].[GetDbType]()
RETURNS VARCHAR(30)
BEGIN
RETURN convert(varchar(30) , (select value from sys.extended_properties where name='DbType' and class_desc='DATABASE') )
END
GO
/****** Object: Default [DF_tb_DataMeta_ObjChangeLog_DbVersion] Script Date: 04/22/2009 13:21:40 ******/
ALTER TABLE [ga].[tb_DataMeta_ObjChangeLog] ADD CONSTRAINT [DF_tb_DataMeta_ObjChangeLog_DbVersion] DEFAULT ('select ga.GetDbVersion()') FOR [DbVersion]
GO
/****** Object: Default [DF_tb_DataMeta_ObjChangeLog_EventDate] Script Date: 04/22/2009 13:21:40 ******/
ALTER TABLE [ga].[tb_DataMeta_ObjChangeLog] ADD CONSTRAINT [DF_tb_DataMeta_ObjChangeLog_EventDate] DEFAULT (getdate()) FOR [EventDate]
GO
/****** Object: Default [DF_tb_DataMeta_ObjChangeLog_ObjVersion] Script Date: 04/22/2009 13:21:40 ******/
ALTER TABLE [ga].[tb_DataMeta_ObjChangeLog] ADD CONSTRAINT [DF_tb_DataMeta_ObjChangeLog_ObjVersion] DEFAULT ('0.0.0') FOR [ObjVersion]
GO
/****** Object: DdlTrigger [trigMetaDoc_TraceDbChanges] Script Date: 04/22/2009 13:21:29 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
create trigger [trigMetaDoc_TraceDbChanges]
on database
for create_procedure, alter_procedure, drop_procedure,
create_table, alter_table, drop_table,
create_function, alter_function, drop_function ,
create_trigger , alter_trigger , drop_trigger
as
set nocount on
declare @data xml
set @data = EVENTDATA()
declare @DbVersion varchar(20)
set @DbVersion =(select ga.GetDbVersion())
declare @DbType varchar(20)
set @DbType =(select ga.GetDbType())
declare @DbName varchar(256)
set @DbName [email protected]('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(256)')
declare @EventType varchar(256)
set @EventType [email protected]('(/EVENT_INSTANCE/EventType)[1]', 'varchar(50)')
declare @ObjectName varchar(256)
set @ObjectName = @data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'varchar(256)')
declare @ObjectType varchar(25)
set @ObjectType = @data.value('(/EVENT_INSTANCE/ObjectType)[1]', 'varchar(25)')
declare @TSQLCommand varchar(max)
set @TSQLCommand = @data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'varchar(max)')
declare @opentag varchar(4)
set @opentag= '<'
declare @closetag varchar(4)
set @closetag= '>'
declare @newDataTxt varchar(max)
set @newDataTxt= cast(@data as varchar(max))
set @newDataTxt = REPLACE ( REPLACE(@newDataTxt , @opentag , '<') , @closetag , '>')
-- print @newDataTxt
declare @newDataXml xml
set @newDataXml = CONVERT ( xml , @newDataTxt)
declare @Version varchar(50)
set @Version = @newDataXml.value('(/EVENT_INSTANCE/TSQLCommand/CommandText/Version)[1]', 'varchar(50)')
-- if we are dropping take the version from the existing object
if ( SUBSTRING(@EventType , 0 , 5)) = 'DROP'
set @Version =( select top 1 [Version] from ga.tb_DataMeta_ObjChangeLog where ObjectName=@ObjectName order by [LogId] desc)
declare @LoginName varchar(256)
set @LoginName = @data.value('(/EVENT_INSTANCE/LoginName)[1]', 'varchar(256)')
declare @FirstName varchar(50)
set @FirstName= (select [FirstName] from [ga].[tb_BLSec_LoginsForUsers] where [LoginName] = @LoginName)
declare @LastName varchar(50)
set @LastName = (select [LastName] from [ga].[tb_BLSec_LoginsForUsers] where [LoginName] = @LoginName)
declare @SchemaName sysname
set @SchemaName = @data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'sysname');
--declare @Description xml
--set @Description = @data.query('(/EVENT_INSTANCE/TSQLCommand/text())')
--print 'VERSION IS ' + @Version
--print @newDataTxt
--print cast(@data as varchar(max))
-- select column_name from information_schema.columns where table_name ='tb_DataMeta_ObjChangeLog'
insert into [ga].[tb_DataMeta_ObjChangeLog]
(
[DatabaseName] ,
[SchemaName],
[DbVersion] ,
[DbType],
[EventType],
[ObjectName],
[ObjectType] ,
[Version],
[SqlCommand] ,
[LoginName] ,
[FirstName],
[LastName]
)
values(
@DbName,
@SchemaName,
@DbVersion,
@DbType,
@EventType,
@ObjectName,
@ObjectType ,
@Version,
@newDataTxt,
@LoginName ,
@FirstName ,
@LastName
)
GO
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER OFF
GO
DISABLE TRIGGER [trigMetaDoc_TraceDbChanges] ON DATABASE
GO
/****** Object: DdlTrigger [trigMetaDoc_TraceDbChanges] Script Date: 04/22/2009 13:21:29 ******/
Enable Trigger [trigMetaDoc_TraceDbChanges] ON Database
GO
私たちはすべてのデータベースをソース管理に移行する過程にあります。私たちはsqlcompareを使ってデータベースを書き出し(プロフェッショナル版の機能、残念ながら)、その結果をSVNに入れています。
実装の成功は、組織の文化と慣行に大きく左右されます。ここの人々はアプリケーションごとにデータベースを作成することを信じています。ほとんどのアプリケーションで使用されるデータベースの共通セットがあり、データベース間の依存関係も多数発生します(それらの一部は循環型です)。データベーススキーマをソース管理にすることは、我々のシステムが持っているデータベース間の依存性のために、非常に困難であった。
幸運を祈ります、あなたが早くそれを試してみるほど早くあなたの問題は整理されるでしょう。
これは私にとっても常に大きな煩わしさでした。開発用データベースをすばやく変更して保存し(変更スクリプトを保存するのを忘れて)たやすい方法ではありません。スクリプトの作成には多くの時間がかかりますが、変更したスクリプトを作成するには、元に戻した作業を元に戻したり、変更スクリプトを作成したりすることもできます。
これを手助けしてきた過去に使用したツールがSQL Deltaです。それはあなたに2つのデータベース(私は信じているSQLサーバー/ Oracle)の違いを示して、A - > Bを移行するのに必要なすべての変更スクリプトを生成します。もう1つ良いことは、本番(またはテスト)DBと開発DBの間のデータベースコンテンツ間のすべての違いを示すことです。データベーステーブルにその実行に不可欠な設定と状態を保存するアプリがますます増えているため、適切な行を削除、追加、および変更するスクリプトを変更することは非常に困難です。 SQL Deltaは、差分ツールで表示されるのと同じようにデータベース内の行を表示します - 変更、追加、削除。
優れた道具これがリンクです: http://www.sqldelta.com/
この質問には多くの良い答えがありますが、それらのほとんどには、特に市販のツールによる、市場における革新的な変化が含まれていません。
これはデータベースのバージョン管理を行うツールの短いリストです、私はそれぞれの長所と短所をリストしました(完全な開示:私はDBmaestroのために働きます)
レッドゲート - 長年にわたって市場に出回っています。ファイルベースのバージョン管理と統合されたスクリプトを使用して、データベースオブジェクトのバージョン管理を提供します。
DBVS - ファイルベースのバージョン管理と統合されたスクリプトを使用してデータベースオブジェクトのバージョン管理を提供します。
DBmaestro - 実際のデータベースオブジェクトに対するバージョン管理プロセス(チェックアウト/チェックイン)の強化を提供します。そのため、バージョン管理リポジトリがアプリケーションで使用されているデータベースと同期していても問題ありません。
私はあなたが彼がLinkedInに投稿したベテランデータベースエキスパートBen Taylorによるデータベース強制変更管理ソリューションに関する包括的で偏りのないレビューを読むことを勧めます https://www.linkedin.com/Pulse/article/20140907002729-287832 - データベース変更の変更 - 管理 - dbmaestro
ThoughtWorksのdbdeployツールを http://dbdeploy.com/ で使っています。それは移行スクリプトの使用を奨励します。リリースごとに、理解を容易にし、DBAが変更を「祝福」できるように、変更スクリプトを1つのファイルに統合しました。
FYIこれもDanaによって数日前に提起されました… ソース管理のストアドプロシージャ/ DBスキーマ
RedGateは素晴らしいです。データベースの変更が行われたときに新しいスナップショットを生成し(小さなバイナリファイル)、そのファイルをリソースとしてプロジェクトに保存します。データベースを更新する必要があるときはいつでも、RedGateのツールキットを使用してデータベースを更新します。また、空のデータベースから新しいデータベースを作成することもできます。
RedGateもデータスナップショットを作成します、私は個人的にはそれらと一緒に働いていませんでしたが、それらは同じくらい堅牢です。
私はすべてのオブジェクト(テーブル定義、インデックス、ストアドプロシージャなど)をスクリプトアウトすることによってデータベーススキーマをソース管理します。しかし、データ自体に関しては、単に定期的なバックアップに頼るだけです。これにより、すべての構造的な変更が適切な改訂履歴で確実にキャプチャされますが、データが変更されるたびにデータベースに負荷がかかることはありません。
私たちのビジネスではデータベース変更スクリプトを使います。スクリプトが実行されると、その名前はデータベースに格納され、その行が削除されない限り再度実行されることはありません。スクリプトは日付、時刻、コード分岐に基づいて命名されているので、制御された実行が可能です。
スクリプトが実際の環境で実行される前に多くのテストが行われるため、「おっと」は開発用データベースでのみ起こります。
私のチームは、私たちのデータベーススキーマをC#クラスとしてコード化し、残りのコードを使っています。クラスを反映し、データベースを構築、削除、および更新するためのSQLコマンドを作成する、自家製C#プログラム(<500行のコード)があります。データベースを作成した後、sqlmetalを実行してlinqマッピングを生成し、それをテストデータの生成に使用される別のプロジェクトでコンパイルします。データアクセスはコンパイル時にチェックされるので、すべてがうまくいきます。スキーマはtrac/svnでcompareを追跡しやすい.csファイルに格納されているので、私たちはそれが好きです。
スクリプトフォルダとのスキーマ同期にはRedGate SQL Compare Proを使用してから、すべての更新をバージョン管理にコミットします。それは素晴らしい仕事です。
RedGateソフトウェアは、データベースのバージョン管理に役立つ優れたツールをいくつか作成します。あなたの開発者が、開発作業用に独自の独立したローカルデータベースを構築するようにしてください。
うわー、非常に多くの答え。確実なデータベースのバージョン管理のためには、データベースを変更するコードをバージョン管理する必要があります。 Drupal 8のような構成管理ツールを提供するCMSもあります。チーム環境でも、 ワークフローを調整し、データベース構成がバージョン管理されるようにする までの実用的な手順の概要を示します。
私は常に自分のデータベース構造がソース管理にダンプされることを確認します。フルデータベースダンプしかし、私は通常圧縮してストレージのために片付けるだけです。
はい。当社のデータベースはERwinで設計されており、各バージョンのDDLは自動的に生成されます。 ERwinファイルは、私たちのソースコード管理システムに保管されています(実際、私たちの工学文書もそうです)。
データベースの管理やバックアップの管理にはレプリケーションとクラスタリングを使用します。 Serenaを使用して、SQLスクリプトと構成の実装を管理します。構成の変更が行われる前に、変更管理プロセスの一環としてバックアップを実行します。このバックアップは、ロールバックの要件を満たしています。
私はそれがすべて規模に依存していると思います。あなたは、オフサイトバックアップと災害復旧を必要とするエンタープライズアプリケーションについて話していますか?会計アプリケーションを実行している小さなワークグループ?それともその間のどこか?
私は sqlHawk この問題を回避する(オープンソースの)ツールを提供することを目的とした作業を始めました。
現在はかなり初期の段階にありますが、すでにストアドとエンフォースメント ストアドプロシージャ とスクリプトによる更新の実行をサポートしています。
このツールを見る時間がある人からのどんな意見にも感謝します。
露骨な自己宣伝をお詫び申し上げますが、これが誰かに役立つことを願っています!
Create/Alterスクリプトがソース管理下にあります。データベース自体については、毎分何百ものテーブルと大量の処理データがある場合、すべてのデータベースをバージョン管理するのはCPUとHDDのキラーになります。私によれば、バックアップがまだあなたのデータを管理する最良の方法であるのはそのためです。
RubyのActiveRecordの移行に関する投稿の多くに同意します。これは、誰でも共有できる小さな増分ファイルでデータベースを管理する上品な方法です。そうは言っても、私は最近VisualStudioのデータベースプロジェクトを使ってプロジェクトを実装しました、そしてそれはちょっと私を信じさせました。簡単な話 - データベースプロジェクトを作成し、既存のデータベースオブジェクト(もしあれば)をそれにインポートします(テーブル/ビュー/トリガ/キー/ユーザー/ etc)。そのインポートにより、オブジェクトごとに「作成」スクリプトが作成されます。データベースを管理するには、createスクリプトを変更してから、デプロイ時にVSがターゲットデータベースをプロジェクト内に存在するデータベースの状態と比較し、適切なalterステートメントを適用します。
それは本当に少し魔法です、そして私が認めなければならない、それはVSチームがしたより良いことの1つです。私はこの点に本当に感心しています。
もちろん、あなたが選択したバージョン管理システムでデータベースプロジェクト全体を管理することができます。
これらのオブジェクトはコードであるため、原則としてすべてのオブジェクトコード(ストアドプロシージャ、ビュー、トリガ、関数など)をソース管理に保持します。他のすべての答えが同意するように、コードは何らかの形式のバージョン管理に属します。システム。
CREATE、DROP、ALTERステートメントなど(DDL)については、ターゲットデータベースに対して1回だけ実行できるように、これらのスクリプトの配置を管理するために BuildMaster を開発して使用します。 (彼らが失敗するかどうか)。一般的な考え方は、開発者は変更スクリプトをシステムにアップロードし、デプロイの時期になると、ターゲット環境のデータベースに対して実行されていない変更スクリプトのみが実行されるということです(これは と非常によく似て管理されます)。オートクラシーの答えは )。スクリプトタイプがこのように分離されているのは、一度テーブルの構造を操作したり、インデックスを追加したりすると、まったく新しいスクリプトを作成したりデータベースを復元したりしなければ、元に戻せないためです。ビューやストアドプロシージャを削除してから再作成するだけです。
たとえば、本番データベースを統合環境に復元した場合、システムは自動的に実行されていないスクリプトを正確に認識し、新しく復元されたデータベースのテーブル構造を最新のものに変更します。開発へ。
私はcreateスクリプトをバージョン管理しており、その中にはsvn versionタグを使用しています。次に、使用されるバージョンを入手するたびに、ロールアップするバージョンとして指定されたdbpatches /ディレクトリにスクリプトを作成します。そのスクリプトの仕事は、データを破壊することなく現在のデータベースを変更することです。たとえば、dbpatches /には、201、220、および240という名前のファイルがあります。データベースが現在レベル201の場合は、パッチ220を適用してからパッチ240を適用します。
DROP TABLE IF EXISTS `meta`;
CREATE TABLE `meta` (
`property` varchar(255),
`value` varchar(255),
PRIMARY KEY (`property`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `meta` VALUES ('version', '$Rev: 240 $');
パッチを考慮する前にコードをテストすることを忘れないでください。買い手責任負担!
Subversionレポジトリに毎週SQLダンプがあります。これは完全に自動化されていますが、本当に厄介な作業です。
実際にはしばらくしてからディスクスペースを消費するので、リビジョンの数を制限したいと思うでしょう。
はい、もちろん。変更があるたびにPostgreSQLスキーマのダンプを生成し、チェックインします。すでに何度も保存されており、数か月しか仕事をしていません。
はい、私たちもSubversionを使ってSQLスクリプトをソース管理しています。これは良い習慣であり、必要に応じていつでもデフォルトのデータでスキーマを再作成できます。
ActiveRecordの移行を使用しています。このRuby gemはRailsプロジェクトの外で使用することができ、あなたが遭遇するほとんどのデータベースを扱うためのアダプターがあります。私のヒント:あなたがPostgresの外であなたのプロジェクトを走らせることができるならば、あなたはトランザクションのスキーマ移行を得る。つまり、移行が半分しか適用されない場合でも、データベースが壊れてしまうことはありません。
Kiraの主な使用例の1つは、コードとしてデータベースの外側のスキーマを明示的に指定することによるデータベースのアップグレードです。その後、データベースを管理し、任意のバージョンから任意のバージョンにアップグレードすることができます。
あなたのプロジェクトチームは、すべての開発者が彼らのcreate alter、delete、insert/update(マスターデータ用)SQLステートメントを転送するDBAを持つことができます。 DBAはこれらのクエリを実行し、必要な更新を正しく行うと、それらのステートメントをテキストファイルまたはスプレッドシートに追加します。各追加はセーブポイントとしてラベル付けできます。特定のセーブポイントに戻る場合は、すべてドロップして、ラベル付きセーブポイントまでクエリを実行します。このアプローチは単なる考えです...ここでの微調整はあなたの開発環境にはうまくいくでしょう。
見過ごされがちな大きな問題は、大規模なWebベースのシステムでは、新しいリリースを作成するための移行期間またはバケットテストのアプローチが必要なことです。これにより、同じDB内で新旧両方のスキーマをサポートするためのロールバックとメカニズムの両方を持つことが不可欠になります。これは足場のアプローチを必要とします(Agile DBの人々によってポピュリストにされました)。このシナリオでは、DBソース管理のプロセスの欠如は大惨事になる可能性があります。システムが完全に新しいバージョンになった(またはロールバックされた)後は、古いスキーマスクリプト、新しいスキーマスクリプト、および一連の中間スクリプトが必要です。
スキーマを最初から再作成するためのスクリプトを用意するのではなく、必要とされるのは状態ベースのアプローチです。あなたのDBは一連の状態スクリプトになり、それは他のソースと共に簡単にソース管理されタグ付けされることができます。
ERツール(PowerAMC)によって生成されたDDL(およびいつかDML)スクリプトを保守します。
シェルブランチ上の数字で始まるスクリプトの名前を変更するシェルスクリプトのベンチがあります。各スクリプトはコミットされており、bugzilla番号が付いています。
これらのスクリプトは、必要に応じてアプリケーションコードとともにリリースブランチ内でマージされます。
スクリプトとそのステータスを記録した表があります。各スクリプトは順番に実行され、展開ツールによって各インストールでこの表に記録されます。
どのデータベースインタフェースコードも、必ずバージョン管理(ストアドプロシージャ、関数など)に含める必要があります。
構造やデータについては、判断の呼びかけです。私は個人的に私のデータベースのきれいな構造的テンプレートを保存していますが、サイズのためにそれらをバージョン管理の中に保存しないでください。しかし、それをバージョン管理で保存することは、履歴を持っているだけの場合でも非常に有益です。
残念ながら、TOAD(データベースツール)のコードを編集するだけで、PL/SQLプログラム(Oracleのストアドプロシージャ)(場合によっては1万LOC)を開発するチームが複数ありました。展開)。データベースが正規化されている場合でも(当然のことですが)、古いバージョンのストアドプロシージャを取得する唯一の方法は、データベース全体を復元することです。もちろん、同じプロジェクトで複数の開発者が作業している場合、1つのファイルに同時に変更を加えると作業が失われることがあります。
スキーマをデータベースに保存しなければならないと人々が言うのを聞いたことがあります。私は同意するかどうかわからない。これは本当にあなたが使っているシステムに依存します。システムが比較的小規模でデータがそれほど重要ではない場合そして、あなたがオンラインで他の開発環境を持ってくる必要があるスピードは非常に重要です。しかし、スキーマがデータなしでは役に立たず、データベースが非常に大きい場合、データベースを「ソース管理」することは事実上不可能になります。確かに、あなたはまだあなたのDDLコードをソース管理のままにすることができますが、それは本質的に役に立ちません。バックアップ/復元なしでは必要なデータを取得することはできません。
大規模なデータベース開発の取り組みでは、バックアップと復元を推奨されるロールバックオプションとして見つけました。プロシージャ、ビュー、関数などをソース管理で管理できることは確かですが、table.sqlを保持する必要はありません。また、展開プロセスが気密であれば、運用環境を「ロールバック」する必要はほとんどないでしょう。
私達は変更スクリプトとマスターデータ定義スクリプトを主張します。これらは他のソースコードとともにCVSにチェックインされます。 PL/SQL(以前はOracleショップでした)もCVSでソース管理されています。変更スクリプトは再現性があり、チームの全員に渡すことができます。基本的に、それがデータベースであるという理由だけで、それをコーディングしてソース管理システムを使って変更を追跡しないという言い訳はありません。
Oracleのために私はSVNの中のOracle DDL方式の自動追跡変更のために自作のJavaプログラム Oracle-ddl2svn を使います