web-dev-qa-db-ja.com

Webサイトを展開するときにデータベースを段階的に更新するにはどうすればよいですか?

私たちは、バッキングプロプライエタリDBと共に、Tomcat経由のJSFを使用します。

新しいバージョンのアプリケーションをデプロイするときに、新しいデータベースフィールドやストアドプロシージャを追加する方法を知りたいのですが。

ホスティングチームにWARファイルを送信してデプロイします。そのため、WARは開始時にストアドプロシージャをセットアップできるはずです。

データベースを段階的に更新できる適切な戦略は何ですか?

5
Archan Mishra

Rails同様のソリューションがフレームワークに組み込まれている世界では特に、Jelaynの答えはかなりよく、標準的な慣行を表しています。しかし、Facebook、Flickrが実施している最新技術、Heroku、およびIMVU(この先駆者)は、もう少し高度です。

標準的なプラクティスの問題は、2つのバージョンのコードを記述し、デプロイ時に迅速な移行で1つのバージョンから別のバージョンに切り替えることができると想定していることです。これには多くの問題があります:

  • データが多い場合、移行には時間がかかります。 Facebookがデータを移行するには数か月かかりますが、データが非常に少ない場合を除いて、移行がすぐに行われることはまれです。これに対する解決策は、ゆっくりと移行することです。 IMVUはここで戦略を開拓しました。

    • テーブルを移行する代わりに、新しいスキーマで別のテーブルを作成します
    • 新しいテーブルに存在しない行が読み取られたら、その行のみを移行して、新しいテーブルに保存します。その後、古い行を削除できます。
    • バッチで移行を実行するバックグラウンドジョブも実行します(競合に注意してください!)
  • 移行中、コードは古いスキーマと新しいスキーマをサポートする必要があります。したがって、両方をサポートするコードを記述してから、移行し、別のデプロイで古いコードを削除する必要があります。

  • 移行が失敗した場合は、両方向に移行できるか、単に順方向に移行できるかを決定する必要があります。 IMVUが進むのは私だけだと思う​​-移行にバグがある場合、ロールバックするのではなく修正する。私は個人的に修正を好むが、それをロールバックすることにも良い議論がある。

このことはすべて継続的な展開にも大きく関係しており、それらの戦略の多くが役立ちます。たとえば、一般的なCD手法では、小規模なユーザーベースに対してのみ新しいコードを選択的に有効にしてより多くのテストを行い、その後、より多くのオーディエンスに対してのみ有効にします(通常、機能ごとにDB設定を使用します)。この方法により、特にフィールドを追加するよりも複雑で、比較的テストされていない移行にすべてのデータを賭けることなく、移行の信頼性を高めることができます。

出典:市場調査および顧客との対話中に、私は 継続的な統合と展開 スタートアップを行います。

4
Paul Biggar

@FrustratedWithFormsDesignerに同意することは可能ですが、データベース構造を更新するためのスクリプトをアプリケーションコードに含めることはできません。このため、アプリケーションは、テーブルの作成、テーブルの変更などを許可する他の権限を必要とします。これらは、アプリケーションの「通常の」使用中にはおそらく必要ないものです。したがって、アプリケーションは適切に動作するために必要な権限のみを持つ必要があるため、セキュリティの観点からは、良いことではありません。

とにかく、要点に戻ります。データベースに特別なテーブル、たとえばX_VERSIONを作成することで適切にそれを行うことはかなり可能です。X_VERSIONを使用すると、データベーススキーマの現在のバージョン(タイムスタンプの場合もある)を簡単に取得できます。データベーススキーマを変更するときはいつでも、その変更を[Timestamp-XXX-WhateverItIsYouAreDoing.sql]という名前のSQLスクリプトに入れます。ここで、

  • タイムスタンプはタイムスタンプです(例:20110111-165500)。
  • XXXは番号で、後でスクリプトの実行順序を知るのに役立ちます
  • 何であれ、そのスクリプトで何をしているのかを思い出すのに役立つテキストです。

データベース更新プログラムがアプリケーション内にあるか外部にあるかは、次の手順では関係ありません。アプリケーションの新しいバージョンを提供するときはいつでも、更新プログラムはこれを行う必要があります。

  • X_VERSIONで現在のタイムスタンプを検索します
  • X_VERSIONにあるバージョンと新しいバージョンの間で実行する必要があるすべてのスクリプトを確認します
  • スクリプトをループし、スクリプトごとに

    • データベース/スキーマを更新するスクリプトを実行します
    • X_VERSIONのタイムスタンプを実行されたスクリプトのタイムスタンプに更新します

すべてのスクリプトが完了すると、アプリケーションを安全に開始できることがわかります。

ボーナス:以前のバージョンに安全に戻る方法が必要な場合は、データベースを変更するスクリプトを作成するたびに、常に以前のバージョンに戻ることができるスクリプトをどこかに作成します。 。時には少し難しいかもしれませんが(たとえば、列を削除するなど、すべてのDBMSがこれを許可しているわけではありません)、常に試してください。その後、必要に応じて以前のバージョンに戻す準備ができます。

4
Jalayn

通常、DBAが実行するスクリプトを使用して、メインアプリケーションの外部にdbの変更をデプロイします。

アプリケーションにデータベース構造を変更する権限がある場合は、アプリケーション内から変更を行うことができると思います。アプリケーションが起動し、起動時にいくつかの新しいプロシージャが実行され、必要なデータベースの変更をすべて行ってから、おそらく再起動する必要があるでしょう。トリックは、変更が確実に発生するようにすることですonce。これはおそらく、特別なテーブルのバージョン番号を確認し、それを使用してデータベースを変更する必要があるかどうかを判断することで実行できます。

また、メインアプリケーションにdbメンテナンスアクティビティを追加しますが、IMOはアプリケーションがおそらく何か他のもの(ブログ、銀行、医療記録、オンラインホテル予約など)を実行するように設計されているため、良い考えではありません。データベースのデプロイメントをコアアプリケーションから完全に分離したい場合があります。

技術的な観点から、これを行うことはかなり可能です。 すべきできるか?それは別の質問です。

私が適用したデータベース更新の2つの標準的なアプローチは次のとおりです。

  1. DBAチームから提供されたSQLスクリプトを実行するデプロイメントチーム。 DBAグループは、スキーマを更新し、その特定のリリースに必要なデータをロードするスクリプトを提供します。
  2. Liquibaseなどの自動化ツールを使用する。このシステムは、@ Jalaynが提案するものと同様のテーブルを追加します。これは、各テーブルに対して実行する必要があるチェンジセット(デルタ)を追跡します。ほとんどの標準操作がサポートされています。

どちらの場合でも、最終結果は同じになります。ただし、使用するアプローチは、開発グループが好む原則(自動vs手動など)を反映する必要があります。

0
JW8