2

現在のデータベース開発環境では、ビルド プロセスを自動化して、svn create database スクリプトからすべての SQL コードをチェックし、それらをさまざまな開発/qa データベースに適用しています。

これはすべて順調で、以前に比べて大幅に改善されていますが、スクリプトの再実行に問題があります。システムに悪影響を与えることなくスクリプトを何度も実行できるため、手順の変更などの一部のスクリプトでは明らかにこれは問題ではありません。現在、メタデータを追加し、create/alter table ステートメントなどのステートメントを実行するために、オブジェクトが存在するかどうかを確認して確認するコードを追加し、存在する場合は実行しないようにします。

私たちの問題は、スクリプトを実行するのに実際には 1 回しか実行できないことです。スクリプトが実行されると、オブジェクトは環境内にあり、システムはスクリプトを再度実行しません。デプロイ後に何かを変更する必要がある場合、更新スクリプトに対して更新スクリプトを実行し、すべてが正しい順序で行われ、すべての PK が環境間で整列することを期待するという困難なプロセスがあります (データベースは、 "特別な")。

データベースを削除して最初からプロセスを開始する以外に (最後の最新リリース)、これに対するより洗練された解決策はありますか?

4

6 に答える 6

2

これ、または少なくともこれと同様の問題に対処するには、次のようにします。

  1. スキーマにはバージョン番号があります。これは、バージョンごとに 1 つの行を持つテーブルで表されます。このテーブルには、バージョン番号だけでなく、そのバージョンが作成された日付/タイム スタンプなどの退屈なものが含まれています。
  2. スキーマの作成/変更 DDL を、変更を実行するコードにラップすることによって。

上記のコンテキストでは、ビルド プロセスの一部としてスキーマ変更コードをビルドして実行し、まだ適用されていないスキーマ変更のみを適用します。

私たちの経験では (これは代表的なものではありません)、ほとんどの場合、スキーマの変更は十分に小さい/高速であるため、トランザクションで安全に実行できます。つまり、失敗した場合はロールバックが発生し、データベースは「安全」です。ただし、実行可能であれば、スキーマの更新を適用する前に常にバックアップを取ることをお勧めします。

私はこれを厄介でつらい経験から発展させました。これは完璧なシステム (または独自のアイデア) ではありませんが、この方法で作業した結果、同じバージョンのデータベースの 1 つのインスタンスが 2 つある場合、それら 2 つのデータベースのスキーマがほとんどすべての点で同じであり、悪影響を与えることなく、そのアプリケーションの現在のスキーマに任意のデータベースを安全に持ち込むことができます。(残念ながら、最後の例は 100% 真実ではありません。例外は常にありますが、真実からかけ離れているわけではありません!)

于 2008-09-08T15:56:42.223 に答える
2

特定の環境で問題にどのようにアプローチするのが最善かはわかりませんが、Rail の移行機能を読んで、開始方法のインスピレーションを得ることをお勧めします。

http://wiki.rubyonrails.org/rails/pages/UnderstandingMigrations

于 2008-09-08T12:38:15.147 に答える
1

既存のデータをデータベースに保持していますか? そうでない場合は、 RikMigrationsと呼ばれる .NET について Matt が言及したものと同様のものを見たいと思うかもしれません。

http://www.rikware.com/RikMigrations.html

プロジェクトでそれを使用して、リビジョンを追跡しながら、その場でデータベースを更新します。また、データベース スキーマを別のサーバーなどに移動することも非常に簡単になります。

于 2008-09-08T12:45:23.947 に答える
0

Scottは、変更管理の問題に対処するSQL ツールをいくつか挙げました。しかし、私はまだ自分自身を転がしています。

私はこの質問を支持し、この問題を解決する無料のコミュニティ ベースのツールがまだないという当惑を付け加えたいと思います。明らかに、スクリプトはデータベース スキーマを維持するための満足のいく方法ではありません。どちらもインスタンスではありません。では、メタデータを別の (プラットフォームに依存しない) 形式で保持しないのはなぜでしょうか?

それが私が今していることです。私のマスター データベース スキーマは、単純な Web サービスから最初に作成された、バージョン管理された XML ファイルです。シンプルな JavaScript プログラムがインスタンスをそれと比較し、シンプルな XSL 変換が CREATE または ALTER ステートメントを生成します。RikMigrationsのように制限があります。たとえば、相互に依存するオブジェクトを常に正しく順序付けするとは限りません。(しかし、何を推測しますか — Microsoft の SQL Server データベース公開ツールもそうではありません。) 本当に、それは単純すぎます。使用していないオブジェクト (ロール、ユーザーなど) を含めなかっただけです。

したがって、私の見解では、この問題は実際には不十分に対処されており、遅かれ早かれ私たちは協力して悪魔のような詳細に取り組まなければならないでしょう.

于 2008-09-08T15:23:05.330 に答える
0

スクリプトに再実行可能性を持たせたい場合、それらを定義として使用することはできません...これが意味するのは、ここにテーブルスクリプトがあるのではなく、変更スクリプトに集中する必要があるということです。

テーブル Customers があるとしましょう:

create table Customers (
   id int identity(1,1) primary key,
   first_name varchar(255) not null,
   last_name varchar(255) not null
)

後でステータス列を追加したいとします。既に実行されている元のテーブル スクリプトを変更しないでください (また、再実行中にエラーが発生しないように if(! exists) 構文を使用できます)。

代わりに、add_customer_status.sql という名前の新しいスクリプトを作成します。

このスクリプトでは、次のようなものになります。

alter table Customers
add column status varchar(50) null

update Customers set status = 'Silver' where status is null

alter table Customers
alter column status varchar(50) not null

ここでも、これを if(! exists) ブロックでラップして再実行できるようにすることができますが、ここでは、これが変更スクリプトであるという概念を活用し、それに応じてデータベースを適応させています。列を追加し、データをシードしてから、not null 制約を追加するので、顧客テーブルに既にデータがある場合でも問題ありません。

上記の移行フレームワークはどちらも優れており、MigratorDotNetについても優れた経験を持っています。

于 2008-09-08T14:45:36.230 に答える
0

「スキーマを削除して再作成する」ルートに進みました。JUnit テスト パッケージにはいくつかのクラスがあり、スクリプトをパラメーター化して、開発者がコードを実行するためのスキーマ内にすべてのオブジェクトを作成しました。これにより、すべての開発者が 1 つのテスト データベースを共有できるようになり、誰もが競合することなくテスト テーブルを同時に作成/テスト/ドロップできました。

実行するのに長い時間がかかりましたか?はい。最初は、これに setup メソッドを使用していました。これは、テストごとにテーブルが削除/作成され、時間がかかりすぎたことを意味していました。次に、クラスのすべてのテストの前に一度実行し、すべてのクラス テストが完了したときにクリーンアップできる TestSuite を作成しました。これは、すべてのパッケージのすべてのテストを含む「AllTests」クラスを実行したときに、db セットアップが何度も実行されたことを意味します。私がそれを解決した方法は、セマフォを OracleTestSuite コードに追加することでした。そのため、最初のテストでデータベースのセットアップが要求されたときにそれが行われますが、その後の呼び出しではカウンターがインクリメントされます。teaDown() メソッドが呼び出されるたびに、カウンターはカウンターを 0 になるまでデクリメントし、OracleTestSuite コードはすべてを破棄します。これが残す問題の 1 つは、テストでデータベースが空であると想定されているかどうかです。データベース テストが実行される順序をデータベース テストに知らせると、DB セットアップの重複を減らすことができるため、データベースの状態を利用できるので便利です。

テスト目的で複雑なドメイン オブジェクトを作成する際の同様の問題を解決するために、ObjectMothers の概念を使用しました。モック オブジェクトの方が良い答えかもしれませんが、当時は聞いたことがありませんでした。結局のところ、典型的なシナリオ用に標準化されたデータセットを作成できるテスト ヘルパー メソッドを作成することをお勧めします。さらに、データの観点から重要なエッジ ケースを文書化するのに役立ちます。

于 2009-07-08T18:56:35.610 に答える