27

さて、これが私たちが直面している問題です。

現在:

  1. データベースに直接アクセスできるレガシーアプリケーションがたくさんあります
  2. データベースのデータ構造は正規化されていません
  3. 現在のプロセス/構造は、ほぼすべてのアプリケーションで使用されています

実装しようとしているもの:

  1. すべての機能を RESTful サービスに移行して、アプリケーションがデータベースに直接アクセスできないようにする
  2. 正規化されたデータ構造を実装する

私たちが抱えている問題は、この移行をアプリケーションだけでなくデータベースにも実装する方法です。

現在の解決策は次のとおりです。

  1. すべての CRUD 機能を特定し、これを新しい Web サービスに実装する
  2. レガシー アプリを置き換える新しいアプリケーションを作成する
  3. 新しいアプリケーションを新しい Web サービスに向ける (まだ古いデータ構造を指している)
  4. データベース内のデータを新しい構造に移行します
  5. 新しいアプリケーションを新しい Web サービスに向ける ( Point to new Data Structure )

しかし、このプロセスについて話し合っているうちに、新しい Web サービスを 2 回書き直す必要があることがわかりました。古いデータ構造に対して 1 回、新しいデータ構造に対して 1 回、現在のところ、古いデータ構造を新しい Web サービスの新しいデータ構造に適合させることはできませんでした。

誰かがこのような課題に直面したことがあるかどうか、また、これらのタイプの問題/実装などをどのように克服したかを知りたいと思いました.

4

3 に答える 3

20

EDIT : 双方向トリガーを使用した同期の詳細な説明; 構文、言語、および明確さの更新。

前文

私は 7 年間取り組んできた大規模な Web アプリケーションのデータ モデルのアップグレードで同様の問題に直面したので、あなたの痛みを感じています。この経験から、私は少し違うものを提案しますが、実装がはるかに簡単になることを願っています. しかし、最初に、観察:

組織にとっての価値はデータです。データは、現在のすべてのアプリケーションよりも長く存続します。ビジネスは、収集したデータから価値を引き出す新しい方法を絶えず発明し、新しいレポート、アプリケーション、およびビジネスの方法を生み出します。

したがって、新しいデータ構造を正しく取得することが最も重要な目標です。他の短期的な開発目標に対して、構造を正しくすることをトレードしないでください。特に:

  • 新サービスの展開などの運用目標
  • パフォーマンスを報告する (代わりに具体化されたビュー、トリガー、またはバッチ ジョブを使用してください)

この構造は時間の経過とともに変化するため、アーキテクチャは頻繁な追加とまれな正規化を可能にする必要があります。これは、データ構造とそれに対する共有 API (RESTful サービスを含む) が適切にバージョン管理されている必要があることを意味します。

なぜ RESTful Web サービスなのか?

「すべての機能をRESTfulサービスに移行して、アプリケーションがデータベースに直接アクセスできないようにする」と述べています。レガシー アプリに関して非常に重要な質問をする必要があります。なぜこれが重要で、どのような価値がもたらされたのでしょうか?

私が尋ねる理由:

  • ACID トランザクションが失われます (恐ろしく複雑な WS-* 標準を実装しない限り、各呼び出しは単一のトランザクションです)。
  • パフォーマンスの低下: データベースへの直接接続は高速になり (Web サーバーの作業や変換が不要)、遅延が少なくなり (通常は 50 ~ 100 ミリ秒ではなく 1 ミリ秒) 、直接 DB 接続用に作成されたアプリケーションの応答性が目に見えて低下します。
  • データベース構造は RESTful サービスから抽象化されていません。データベースの正規化では、Web サービスを書き直し、それらを呼び出すアプリケーションを書き直す必要があることを認識しているためです。

その他の分野横断的な懸念事項は変更されていません。

  • 管理性: ここにある多くの汎用ツールを使用して、データベースへの直接接続を監視および管理できます。
  • セキュリティ: 直接接続は、開発者が作成する Web サービスよりも安全です。
  • 承認: データベースのアクセス許可モデルは非常に高度で、必要に応じてきめ細かく設定されています
  • スケーラビリティ: Web サービスは (唯一の?) 直接接続されたデータベース アプリケーションであるため、データベースと同じくらいしかスケーリングしません。

従来の RESTful API を維持することで、データベースを移行し、従来のアプリケーションを実行し続けることができます。しかし、「レガシー」RESTful サービスを導入せずにレガシー アプリを維持できるとしたらどうでしょう。

データベースのバージョン管理

おそらく、「レガシー」アプリケーションの大半は、SQL を使用してデータ テーブルに直接アクセスします。データベース ビューも多数ある場合があります。

データ移行の 1 つのアプローチは、新しいデータベース (新しいスキーマに新しい正規化された構造を持つ) が古い構造を従来のアプリケーション (通常は別のスキーマから) へのビューとして提示することです。

これは実際には非常に簡単に実装できますが、レポート機能と読み取り専用機能のみが解決されます。レガシー アプリケーションの DML はどうですか? DMLは次を使用して解決できます

  • 単純な変換のための更新可能なビュー
  • 更新可能なビューが不可能なストアド プロシージャの導入 (たとえば、"INSERT INTO EMP (col1, col2, col3) VALUES (?, ? ?)" ではなく "CALL insert_emp(?, ?, ?)")。
  • トリガーと DB リンクを使用して新しいデータベースと同期する「レガシー」テーブルを用意します。

トリガーを使用して新しい形式のテーブルへの双方向同期を備えたレガシー形式のテーブルを持つことは、力ずくの解決策であり、比較的醜いです。

2 つの異なるスキーマ (またはデータベース) に同一のデータが存在することになり、同期コードにバグがあるとデータが同期しなくなる可能性があり、「2 つのマスター」の問題という古典的な問題が発生します。そのため、これは最後の手段として扱ってください。たとえば、次のような場合です。

  • 基本構造が変更された (例えば、リレーションのカーディナリティの変更)、または
  • 従来の形式への変換は複雑な関数です (たとえば、従来の列が新しい形式の列の値の 2 乗であり、「4」に設定されている場合、更新可能なビューは正しい値が +2 か -2 かを判断できません)。 .

データにそのような変更が必要な場合、コードとロジックのどこかで大幅な変更が行われます。互換レイヤーに実装するか (利点: レガシー コードを変更しない)、またはレガシー アプリを変更できます (利点: データ レイヤーはクリーンです)。これは、エンジニアリング チームによる技術的な決定です。

上記のアプローチを使用してレガシー構造の互換性データベースを作成すると、レガシー アプリケーションへの変更を最小限に抑えることができます (場合によっては、コードをまったく変更せずにレガシー アプリケーションを継続できます)。これにより、開発とテストのコストが大幅に削減され (ビジネスにとって正味の機能向上はありません)、ロールアウトのリスクが大幅に削減されます。

また、組織にとっての真の価値に集中することもできます。

  • 新しいデータベース構造
  • 新しい RESTful Web サービス
  • 新しいアプリケーション (RESTful Web サービスを使用して構築される可能性があります)

Web サービスの良い点

上記を Web サービス、特に RESTful Web サービスに対する批判として読まないでください。Web アプリケーションの有効化や異種システム間の統合など、適切な理由で使用する場合、これは優れたアーキテクチャ ソリューションです。ただし、データ移行中にレガシー アプリを管理するための最適なソリューションではない可能性があります。

于 2012-11-28T03:27:01.393 に答える
2

あなたがしなければならないように思われるのは、新しいデータモデル(「正規化」)を定義し、正規化されたモデルからレガシーモデルへのマッピングを構築することです。その後、レガシ ダイレクト コールを正規化されたコールに自由に置き換えることができます。これはコードを壊しません。

並行して、(認証された) レガシー db API に相当するものを定義し、それを正規化されたモデルにマップする必要があります。ここで、暇なときに、元のレガシー db 呼び出しをレガシー db API の呼び出しに置き換えます。これはコードを壊しません。

元の呼び出しが完全に置き換えられたら、データ モデルを実際の正規化されたモデルに切り替えることができます。すべてが従来の db API または正規化された db API に反するため、これによってコードが壊れることはありません。

最後に、従来の db API 呼び出しと関連コードを、正規化されたデータ API を使用する改訂されたコードに置き換えることができます。これには、注意深い再コーディングが必要です。

これらすべてを高速化するには、自動化されたコード変換ツールでコード置換を実装する必要があります。

このドキュメントには概要がよく示されているようです: http://se-pubs.dbs.uni-leipzig.de/files/Cleve2006CotransformationsinDatabaseApplicationsEvolution.pdf

于 2012-11-17T21:36:25.930 に答える
1

まず、これは非常に厄介な状況のように思えます。「クリーンな」解決策はないと思います。私は似たような状況を数回経験しましたが、あまり楽しくありませんでした。

まず、クライアント アプリを変更する作業は重要です。基になるドメインが変更された場合 (たとえば、個人とは別のアドレスの概念を導入することによって)、クライアント アプリも変更されます。これは単なる変更ではありません。データにアクセスする方法。この問題を回避する最善の方法は、将来のビジネス ドメイン モデルを反映するように API レイヤーを記述し、古いデータベース スキーマをそれに接着することです。古いデータを使用して反映できない新しい概念がある場合 (例: "get /app/addresses/addressID")、NotImplemented エラーをスローします。古いデータで新しいモデルを反映できる場合は、できる限りそれらを結び付けてから、内部でリファクタリングします。

第 2 に、これは、API にバージョニングを第一級の懸念事項として組み込む必要があることを意味します。これにより、バージョン 1 では機能 x、y、および z が「NotImplemented」例外をスローすることをクライアントに伝えることができます。各バージョンは下位互換性がありますが、新しい機能が追加されています。そうすれば、サービスを壊さない限りバージョン 1 の機能をリファクタリングし、機能 x をバージョン 1.1 に、機能 y をバージョン 1.2 などに実装できます。理想的には、バージョンのロードマップを用意し、クライアント アプリに通知します。バージョンのサポートを停止する場合、または重大な変更をリリースする場合は、所有者に連絡してください。

第 3 に、API の一連の自動化された統合テストは、リファクタリング時に機能が壊れていないことを確認するための最善の投資です。

これがお役に立てば幸いです。あなたの質問に対する単純な答えは 1 つではないと思います。

于 2012-11-27T15:37:34.117 に答える