実稼働データベースへのスキーマのアップグレードはどのように管理しますか?

StackOverflow https://stackoverflow.com/questions/29744

  •  09-06-2019
  •  | 
  •  

質問

これは見落とされている領域のようですが、実際にはいくつかの洞察が必要です。ベストプラクティスは何ですか:

  • アップグレード手順を作成する
  • エラーが発生した場合のバックアウト
  • コードとデータベースの変更を同期する
  • 導入前のテスト
  • テーブル変更の仕組み

等...

役に立ちましたか?

解決

素晴らしい質問ですね。( これは、正規化データベースと非正規化データベースの議論に終わる可能性が高いです。私はそれを始めるつもりはありません...さて、入力してください。)

私がやったことのいくつかを頭の中に思い浮かべます(もう少し時間があるとき、または休憩が必要なときにさらに追加します)

クライアントの設計 - ここで、VB のインライン SQL メソッド (プリペアド ステートメントを使用する場合でも) が問題に陥ります。これらのステートメントを見つけるだけで AGES を費やすことができます。Hibernate のようなものを使用し、できるだけ多くの SQL を名前付きクエリに入力すると、ほとんどの SQL を 1 つの場所で処理できます (IF ステートメント内にある SQL をテストしようとして「トリガー」にヒットしないことほど悪いことはありません)その IF ステートメントのテストの基準)。Hibernate (または他の orms) を使用する前は、JDBC または ODBC で SQL を直接実行するときに、すべての SQL ステートメントをオブジェクトのパブリック フィールド (命名規則に従って) またはプロパティ ファイル (これも命名規則に従って) に入れていました。値の規則では PREP_STMT_xxxx となります。そして、a) テストケース b) アプリケーションの起動時に、起動時に値のリフレクションまたは反復を使用します (一部の RDBMS では、実行前に準備済みステートメントをプリコンパイルできるため、ログイン後の起動時に準備済みステートメントをプリコンパイルします)。起動時に stmts を使用してアプリケーションを自己テストします。優れた RDBMS 上で数百のステートメントを実行する場合でも、わずか数秒で完了します。そして一度だけ。そしてそれは私のお尻を大いに救ってくれました。あるプロジェクトでは、DBA がコミュニケーションをとらず (別の国の別のチーム)、理由もなくスキーマが毎晩変更されているように見えました。そして毎朝、起動時にアプリケーションを破壊した正確な場所のリストを取得しました。

アドホック機能が必要な場合は、それを適切な名前のクラスに置きます (つまり、繰り返しますが、命名規則は自動テストに役立ちます)、クエリに対するある種のファクトリーとして機能します(つまり、クエリを構築します)。いずれにせよ、同等のコードを記述する必要があります。テストできる場所に置くだけです。同じオブジェクトまたは別のクラスにいくつかの基本的なテスト メソッドを記述することもできます。

可能であれば、ストアド プロシージャも使用してみてください。上記と同様に、テストするのが少し難しくなります。一部の DB では、実行時のみコンパイル時にストアド プロシージャ内の SQL をスキーマに対して事前検証しません。通常、これには、スキーマ構造 (データなし) のコピーを取得し、このコピーに対してすべてのストアド プロシージャを作成することが含まれます (変更を行った DB チームが正しく検証されなかった場合に備えて)。このようにして構造を確認することができます。しかし、変更管理の点としては、ストアドプロシージャは優れています。変更すると、すべてがわかります。特に、データベースの変更がビジネス プロセスの変更の結果である場合は特にそうです。そしてすべての言語 (Java、VB など) が変更されます。

通常、system_setting などと呼ばれるテーブルもセットアップします。このテーブルでは、VERSION 識別子を保持します。これは、クライアント ライブラリが接続して、このバージョンのスキーマに対して有効かどうかを検証できるようにするためです。スキーマへの変更によっては、スキーマが破損する可能性があるクライアントの接続を許可したくない場合があります。データベースには多くの参照ルールはありませんが、クライアントにはあります)。複数のクライアント バージョンを使用するかどうかによって異なります (非 Web アプリ、つまり、Web アプリではこれが発生します。間違ったバイナリを実行しています)。バッチツールなども使用できます。私が行ったもう 1 つのアプローチは、ある種のプロパティ ファイルまたは system_info テーブルで操作バージョンに対するスキーマのセットを定義することです。このテーブルはログイン時にロードされ、各「マネージャー」(通常、ほとんどの DB 作業を行うために何らかのクライアント側 API を持っています)によって使用され、その操作が正しいバージョンであるかどうかを検証します。したがって、ほとんどの操作は成功しますが、古いメソッドでは失敗する (例外をスローする) こともあり、その理由がわかります。

スキーマへの変更を管理します -> テーブルを更新しますか、それとも新しいテーブルに 1 対 1 の関係を追加しますか?この理由から、常にビューを介してデータにアクセスしているショップを多く見てきました。これにより、テーブル名、列などを変更できるようになります。私は実際にビューを COM のインターフェイスのように扱うというアイデアを試してみました。つまり。新しい機能/バージョンに対して新しい VIEW を追加します。多くの場合、ここにたどり着くのは、テーブル形式を前提としたレポート (特にエンド ユーザーのカスタム レポート) が多数存在する可能性があるということです。ビューを使用すると、新しいテーブル形式を展開できますが、既存のクライアント アプリもサポートされます (厄介なアドホック レポートをすべて思い出してください)。

また、更新スクリプトとロールバック スクリプトを作成する必要があります。そしてまたテスト、テスト、テスト...

------------ わかりました - ちょっとランダムなディスカッションの時間です --------------

実は大規模な商業プロジェクトがありました。ソフトウェアショップ)でも同じ問題が発生しました。アーキテクチャは 2 層で、PHP に少し似ているが PHP 以前の製品を使用していました。同じこと。違う名前。とにかく、私はバージョン2で来ました...

アップグレードには多額の費用がかかりました。たくさん。つまり。現場で数週間の無料コンサルティング時間を提供します。

そして、新しい機能を追加するか、コードを最適化する必要があるところまで来ていました。既存のコードの一部はストアド プロシージャを使用していたので、コードを管理できる共通点がありました。しかし、他の領域は HTML に埋め込まれた SQL マークアップでした。これは、迅速に市場に投入するのに最適でしたが、新機能が追加されるたびに、テストと保守のコストが少なくとも 2 倍になりました。そこで、PHP タイプのコードを取り出し、データ層 (これは 2001 年から 2002 年で、ORM が登場する前など) を追加し、多くの新機能 (顧客からのフィードバック) を追加することを検討していたとき、アップグレードをどのように設計するかというこの問題に注目しました。システムに。アップグレードを正しく行うには多額の費用がかかるため、これは大きな問題です。さて、人々がある程度のエネルギーを持って議論するほとんどのパターンやその他の事柄は、実行中の OO コードを扱いますが、データが a) このロジックに統合されなければならない、b) の意味と構造はどうでしょうか。データは時間の経過とともに変化する可能性があり、多くの場合、データの仕組みが原因で、そのデータを必要とするクライアント組織内に多くのサブプロセス/アプリケーションが存在することになります -> アドホック レポートや複雑なカスタム レポート、さらにはバッチ ジョブカスタム データ フィードなどのために行われています。

これを念頭に置いて、私はフィールドから少し離れたもので遊び始めました。また、いくつかの仮定もあります。a) データは書き込みよりも読み取りが頻繁に行われます。b) 更新は行われますが、バンク レベルでは行われません。1秒に1つか2つ言います。

このアイデアは、COM / インターフェイス ビューを、一連の CONCRETE テーブル (スキーマの変更によって変化する) を介してクライアントがデータにアクセスする方法に適用することでした。更新、削除、挿入、読み取りなどの操作タイプごとに個別のビューを作成できます。これは重要。ビューはテーブルに直接マップするか、実際の更新や挿入などを行うダミーテーブルのトリガーを可能にします。私が実際に欲しかったのは、クリスタルレポートなどでまだ使用できる、ある種のトラップ可能なレベルの間接的なものでした。注 - 挿入、更新、削除の場合は、ストアド プロシージャを使用することもできます。そして、製品のバージョンごとにバージョンがありました。そうすることで、バージョン 1.0 のスキーマのバージョンが変更され、テーブルが変更された場合でも、必要に応じて新しいテーブルにマップする新しいバックエンド ロジックを備えたバージョン 1.0 のビューが残りますが、サポートするバージョン 2.0 のビューも持つことになります。新しい分野などこれは実際にはアドホック レポートをサポートするためのもので、プログラマーではなくビジネス担当者であれば、おそらくこれがこの製品を使用する理由の最大のポイントです。(あなたの製品はクソかもしれませんが、世界で最高のレポートを持っていればまだ勝てる可能性があります。逆も真です。あなたの製品は機能的には最高かもしれませんが、レポートの方が劣っていれば、簡単に負ける可能性があります)。

わかりました。これらのアイデアがお役に立てば幸いです。

他のヒント

リキベース

liquibase.org:

  1. Hibernate の定義を理解します。
  2. 休止状態よりも優れたスキーマ更新 SQL を生成します。
  3. データベースにどのアップグレードが行われたかを記録します。
  4. 2 段階の変更を処理します (つまり、列「foo」を削除してから、別の列の名前を「foo」に変更します)
  5. 条件付きアップグレードの概念を処理します
  6. 開発者は実際にコミュニティの意見に耳を傾けます (群衆の中にいない場合や初心者の場合は休止状態を使用します。基本的に無視されます)。

http://www.liquibase.org

意見

アプリケーションは 一度もない スキーマの更新を処理します。これは起こるのを待っている災害です。データはアプリケーションよりも長く存続し、複数のアプリケーションが同じデータを操作しようとするとすぐに (たとえば、本番アプリとレポート アプリ)、両方とも同じ基礎となる企業ライブラリを使用する可能性があります...そして、両方のプログラムが独自の DB アップグレードを実行することを決定します...を楽しんでいます それ 混乱。

私は大ファンです レッドゲート データベース スキーマを更新する SQL パッケージの作成を支援する製品。データベース スクリプトをソース管理に追加すると、バージョン管理とロールバックに役立ちます。

一般的に私のルールは次のとおりです。「アプリケーションは独自のスキーマを管理する必要があります。」

つまり、スキーマ アップグレード スクリプトはアプリケーションのアップグレード パッケージの一部であり、アプリケーションの起動時に自動的に実行されます。エラーが発生した場合、アプリケーションは起動に失敗し、アップグレード スクリプトのトランザクションはコミットされません。この欠点は、アプリケーションがスキーマへの完全な変更アクセス権を持っている必要があることです (これは DBA を悩ませます)。

Hibernates SchemaUpdate 機能を使用してテーブル構造を管理することに成功しました。実際のデータの初期化と列の時折の削除のみをアップグレード スクリプトに任せておきます (SchemaUpdate はそれを行いません)。

テストに関しては、アップグレードはアプリケーションの一部であるため、アップグレードのテストはアプリケーションのテスト サイクルの一部になります。

結果論:他の投稿での批判の一部をここで取り上げますが、ルールが「独自のもの」であることに注意してください。実際に適用されるのはアプリケーションの場合のみです 所有している 製品として販売されるソフトウェアの場合と同様のスキーマ。ソフトウェアが他のソフトウェアとデータベースを共有している場合は、他の方法を使用してください。

これらはすべて重要なトピックですが、更新するための私の推奨事項は次のとおりです。

プラットフォームは指定されていませんでしたが、私が使用している NANT ビルド環境では タランティーノ. 。コミットする準備ができているデータベース更新ごとに、(RedGate または別のツールを使用して) 変更スクリプトを作成します。本番環境にビルドすると、Tarantino はスクリプトがデータベース上で実行されたかどうかをチェックします (追跡するためにデータベースにテーブルが追加されます)。そうでない場合は、スクリプトが実行されます。すべて手作業が必要です (読んでください:人的ミス) により、データベースのバージョン管理が失われます。

パットが言ったように、リキベースを使用してください。特に、独自の開発データベースを持つ開発者が複数の開発者がいる場合は、制作データベースの一部になる変更を加えます。

私が現在参加している 1 つのプロジェクトのように、開発者が 1 人しかいない場合は (笑)、スキーマの変更を SQL テキスト ファイルとして CVS リポジトリにコミットし、コードの変更が入ったときに実稼働サーバー上でバッチでチェックアウトします。 。

しかし、liquibase はそれよりも優れています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top