これは、いくつかの洞察を実際に使用できる見過ごされている領域のようです。あなたのベストプラクティスは何ですか:
- アップグレード手順の作成
- エラーの場合のバックアウト
- コードとデータベースの変更の同期
- 展開前のテスト
- テーブルを変更する仕組み
等...
これは、いくつかの洞察を実際に使用できる見過ごされている領域のようです。あなたのベストプラクティスは何ですか:
等...
liquibase.org:
意見
アプリケーションがスキーマの更新を処理することはありません。これは起こるのを待っている災害です。データはアプリケーションより長持ちし、複数のアプリケーションが同じデータ (たとえば、運用アプリとレポート アプリ) を操作しようとするとすぐに、両方が同じ基になる会社のライブラリを使用する可能性があります...そして、両方のプログラムが独自のデータベースのアップグレードを行います...その混乱を楽しんでください。
一般的に、私のルールは次のとおりです。「アプリケーションは独自のスキーマを管理する必要があります」。
これは、スキーマ アップグレード スクリプトがアプリケーションのアップグレード パッケージの一部であり、アプリケーションの起動時に自動的に実行されることを意味します。エラーが発生した場合、アプリケーションは起動に失敗し、アップグレード スクリプト トランザクションはコミットされません。これの欠点は、アプリケーションがスキーマへの完全な変更アクセス権を持っている必要があることです (これは DBA を悩ませます)。
Hibernates SchemaUpdate 機能を使用してテーブル構造を管理することに成功しました。アップグレード スクリプトは、実際のデータの初期化と時折の列の削除のみを処理するようにします (SchemaUpdate はそれを行いません)。
テストに関しては、アップグレードはアプリケーションの一部であるため、アップグレードのテストはアプリケーションのテスト サイクルの一部になります。
後付け: ここにある他の投稿での批判の一部を取り入れて、ルールには「それは独自のものです」と書かれていることに注意してください。製品として販売されるソフトウェアの場合と同様に、アプリケーションがスキーマを所有する場合にのみ実際に適用されます。ソフトウェアが他のソフトウェアとデータベースを共有している場合は、他の方法を使用してください。
私は、データベース スキーマを更新するための SQL パッケージの作成を支援するRed Gate製品の大ファンです。データベース スクリプトをソース管理に追加して、バージョン管理とロールバックに役立てることができます。
それは素晴らしい質問です。(これにより、正規化されたデータベースと非正規化されたデータベースの議論が終わる可能性が高くなります。これについては開始しません...いくつかの入力については問題ありません。)
私がやったことの頭のてっぺんからいくつか(私がもう少し時間があるか、休憩が必要なときにもっと追加します)
クライアントの設計-これは、インラインSQLのVBメソッド(プリペアドステートメントを使用している場合でも)で問題が発生する場所です。あなたはそれらのステートメントを見つけるだけでAGESを使うことができます。Hibernateのようなものを使用し、名前付きクエリにできるだけ多くのSQLを入れると、ほとんどのSQLを1か所にまとめることができます(IFステートメント内にあるSQLをテストしようとしても、「トリガー」を押さないでください。そのIFステートメントのテストの基準)。JDBCまたはODBCでSQLを直接実行するときにhibernate(または他のorms)を使用する前は、すべてのsqlステートメントをオブジェクトのパブリックフィールド(命名規則を使用)またはプロパティファイル(命名規則を使用)として配置していました。値の規則はPREP_STMT_xxxxと言います。わずか数秒の優れたrdbmsでの数百のステートメントでも。そして一度だけ。そして、それは私のお尻を大いに救いました。あるプロジェクトでは、DBAは通信せず(別の国の別のチーム)、スキーマは理由もなく一晩で変更されたように見えました。そして毎朝、起動時にアプリケーションが壊れた場所の正確なリストを取得しました。わずか数秒の優れたrdbmsでの数百のステートメントでも。そして一度だけ。そして、それは私のお尻を大いに救いました。あるプロジェクトでは、DBAは通信せず(別の国の別のチーム)、スキーマは理由もなく一晩で変更されたように見えました。そして毎朝、起動時にアプリケーションが壊れた場所の正確なリストを取得しました。
アドホック機能が必要な場合は、クエリのファクトリとして機能する(つまり、クエリを構築する)適切な名前のクラスに配置します(つまり、命名規則は自動テストに役立ちます)。とにかく同等のコードを作成する必要があります。テストできる場所に配置するだけです。同じオブジェクトまたは別のクラスにいくつかの基本的なテストメソッドを作成することもできます。
可能であれば、ストアドプロシージャも使用してみてください。上記のようにテストするのは少し難しいです。一部のデータベースは、コンパイル時のみ実行時に、ストアドプロシージャのSQLをスキーマに対して事前検証しません。これには通常、スキーマ構造のコピー(データなし)を取得し、このコピーに対してすべてのストアドプロシージャを作成することが含まれます(変更を行うdbチームが正しく検証されなかった場合)。したがって、構造を確認することができます。しかし、変更管理のポイントとして、ストアドプロシージャは素晴らしいです。変更時にすべてがそれを取得します。特に、データベースの変更がビジネスプロセスの変更の結果である場合。そして、すべての言語(java、vbなどが変更されます)
私は通常、system_settingなどと呼ばれる使用するテーブルも設定します。このテーブルでは、VERSION識別子を保持します。これは、クライアントライブラリが接続して、このバージョンのスキーマに対して有効かどうかを検証できるようにするためです。スキーマへの変更によっては、クライアントがスキーマを破損する可能性がある場合(つまり、データベースに多くの参照ルールがないがクライアントにある場合)にクライアントが接続することを許可したくない場合があります。複数のクライアントバージョンを使用するかどうかによって異なります(これは、非Webアプリで発生します。つまり、間違ったバイナリを実行しています)。バッチツールなどを使用することもできます。私が行ったもう1つのアプローチは、ある種のプロパティファイルまたはsystem_infoテーブルでバージョンを操作するためのスキーマのセットを定義することです。このテーブルはログイン時にロードされ、各「マネージャー」によって使用されます (私は通常、ほとんどのデータベース作業を行うためのある種のクライアント側APIを持っています)それが正しいバージョンであるかどうかを検証するために。したがって、ほとんどの操作は成功する可能性がありますが、古いメソッドで失敗する(いくつかの例外をスローする)こともでき、その理由がわかります。
スキーマへの変更の管理->テーブルを更新しますか、それとも新しいテーブルに1-1の関係を追加しますか?このため、常にビューを介してデータにアクセスするショップをたくさん見ました。これにより、テーブル名や列などを変更できます。私は、実際にビューをCOMのインターフェイスのように扱うというアイデアを試しました。すなわち。新しい機能/バージョンの新しいビューを追加します。多くの場合、ここで得られるのは、テーブル形式を想定した多くのレポート(特にエンドユーザーのカスタムレポート)を作成できることです。ビューを使用すると、新しいテーブル形式をデプロイできますが、既存のクライアントアプリをサポートできます(これらの厄介なアドホックレポートをすべて覚えておいてください)。
また、更新スクリプトとロールバックスクリプトを作成する必要があります。そして再びテスト、テスト、テスト...
------------OKAY-これは少しランダムなディスカッション時間です--------------
実際、同じ問題を抱えていた大規模な商業プロジェクト(つまりソフトウェアショップ)がありました。アーキテクチャは2層で、PHPに少し似ていますが、PHP以前の製品を使用していました。同じこと。別の名前。とにかく私はバージョン2で入ってきました...
アップグレードを行うには多額の費用がかかりました。多くの。すなわち。現場で数週間の無料コンサルティング時間を提供します。
そして、新しい機能を追加するか、コードを最適化する必要が出てきました。既存のコードの一部はストアドプロシージャを使用していたため、コードを管理できる共通点がありました。しかし、他の領域は、htmlに埋め込まれたSQLマークアップでした。これは、市場に迅速に参入するのに最適でしたが、新機能が相互作用するたびに、テストと保守のコストが少なくとも2倍になりました。したがって、phpタイプのコードを引き出し、データレイヤーを配置し(これは2001年から2002年、ORMの前など)、多くの新機能(顧客からのフィードバック)を追加することを検討していたとき、アップグレードのエンジニアリング方法に関するこの問題を検討しました。システムに。アップグレードを正しく行うには多くの費用がかかるため、これは大きな問題です。さて、ほとんどのパターンと人々がある程度のエネルギーで議論する他のすべてのものは、実行中のOOコードを扱います。
これを念頭に置いて、私はフィールドの少し左にある何かで遊び始めました。また、いくつかの仮定があります。a)データは書き込みよりも読み取りが多い。b)更新は行われますが、銀行レベルでは発生しません。1秒か2秒と言います。
アイデアは、COM /インターフェイスビューを、一連のCONCRETEテーブル(スキーマの変更によって異なる)を介してクライアントがデータにアクセスする方法に適用することでした。タイプ操作(更新、削除、挿入、読み取り)ごとに個別のビューを作成できます。これは重要。ビューは、テーブルに直接マップするか、実際の更新や挿入などを行うダミーテーブルをトリガーできるようにします。実際に必要だったのは、CrystalReportsなどで引き続き使用できるトラップ可能なレベルの間接参照です。 -挿入、更新、削除には、ストアドプロシージャを使用することもできます。そして、製品の各バージョンのバージョンがありました。このように、バージョン1.0にはそのバージョンのスキーマがあり、テーブルが変更された場合でも、バージョン1.0のビューがありますが、必要に応じて新しいテーブルにマップするための新しいバックエンドロジックがありますが、バージョン2もあります。新しいフィールドなどをサポートする0ビュー。これは、アドホックレポートをサポートするためだけのものでした。これは、コーダーではなくビジネスパーソンの場合、おそらく製品を持っている理由のすべてのポイントです。(あなたの製品はがらくたである可能性がありますが、あなたがまだ勝つことができる世界で最高のレポートを持っているなら、その逆が真実です-あなたの製品は賢明な最高の機能である可能性がありますが、レポートが悪い場合は非常に簡単に失う可能性があります)。
さて、それらのアイデアのいくつかが役立つことを願っています。
これらはすべて重要なトピックですが、更新するための私の推奨事項は次のとおりです。
プラットフォームは指定されていませんが、NANT ビルド環境ではTarantinoを使用します。コミットする準備ができているデータベースの更新ごとに、変更スクリプトを作成します (RedGate または別のツールを使用)。本番環境にビルドすると、Tarantino はスクリプトがデータベースで実行されたかどうかをチェックします (追跡するためにデータベースにテーブルが追加されます)。そうでない場合は、スクリプトが実行されます。データベースのバージョンを管理するためのすべての手作業 (読み: 人的エラー) が不要になります。
iBATIS 3スキーマ移行システムについて良いことを聞いたことがあります:
ユーザーガイド:http ://svn.apache.org/repos/asf/ibatis/java/ibatis-3/trunk/doc/en/iBATIS-3-Migrations.pdf
パットが言ったように、リキベースを使用してください。特に、本番データベースの一部になる変更を行う独自の開発データベースを持つ複数の開発者がいる場合。
私が現在取り組んでいる 1 つのプロジェクトのように (ha)、開発者が 1 つしかない場合は、スキーマの変更を SQL テキスト ファイルとして CVS リポジトリにコミットし、コードの変更が行われたときに本番サーバーでバッチでチェックアウトします。 .
しかし、liquibase はそれよりも優れています。