2

私はここでいくつかの遅い操作を加速することに取り組んでいます、そして1つのケースはテーブルの親子関係のツリーです。現在、システムはSQLServerで実行されており、調査の結果、一般的なテーブル式を使用すると、複数のクエリを1つにまとめることができることがわかりました。

これまでのところ良いですが、構文はSQLServerに固有であり、(たとえば)Oracleで同じことを行うには、完全に異なる構文が必要になります。

他のRDBMSへの将来の適応を可能にするためにシステムを構築するために何ができるでしょうか?ここでの私の主な関心事は次のとおりです。

  • SQLステートメントはコード上に散らばっていて、あるRDBMSの1つのステートメントで可能なことは、別のRDBMSで複数のステートメントを必要とする場合があるため、プログラムロジックでさえ変更が必要になる場合があります。
  • 1つのRDBMSにうまくカプセル化できるもの(私は保存された関数を使用してDBの複雑さの一部を隠しています)でさえ、異なるDBに沿って微妙な違いがあるか、まったく利用できません。

これまでのところ、最も単純なSQLステートメントを超えるものはすべて、常にベンダー固有の拡張機能を必要としているように思われるため、いくつかのクラス/格納されたSQLで違いをきちんと隠しておくことは不可能です(抽象化はすでに組み込まれています。しかし、それはDBのより便利な機能の多くも除外します)。

少なくともベンダーの違いによる苦痛を和らげるために、どのような戦略を使用できますか?これは非常に幅広い質問であり、すべてを解決することはできません。しかし、DBがアプリケーションに与える影響を軽減するためのいくつかのポインターとパターンを期待しています。

編集:実装言語はJavaであり、単にORM(Hibernateなど)を使用することは私が探しているものではありません(多かれ少なかれコードベースの約50%を書き直す必要があります)。

EDIT2:私は主に、可能な限り一般的に互換性のある方法でデータベースに詳細をプッシュする可能性を探しています。理想的には、Java部分で使用されるSQLをすべてのプラットフォームで同じにする必要があります(または非常に必要なだけです)構文の違いによるわずかな変更)。私が提供したCTEの例では、移植が必要になったときに機能を関数でも再現できることを期待して、現在それをストアド関数にプッシュしています。

EDIT3:現在、他のRDBMをサポートする差し迫った必要はありません。SQLServerでのみ機能する場合、誰も私を責めることはありません。しかし、可能であれば、Javaコードを特定のDBベンダーに必要以上に結び付けることは避けたいと思います。

EDIT4:いくつかの背景-現在の作業は、システムに機能を追加することです-それが設​​計も計画もされていなかった機能。要件は、ビジネスマンから少しずつ細かくなり、事前に計画するのは困難です。それぞれの要件自体を解決するのはそれほど難しいことではありませんが、すべてのクエリを詳細に調べないと移植できないものにタグ付けされたものの大きな混乱が蓄積されるのではないかと心配しています。SQLServer自体も、メジャーな新しいリリースごとにさまざまな非互換性を導入しているため、新しいSQLServerに切り替えることでさえ、将来的に大きな障害になる可能性があるのではないかと心配しています(過去に、2005年から2008年にそのようなアップグレードを1回行いました。私が維持しているものについてはスムーズですが、それはすでに私たちのサプライヤーの1つに多くの問題を引き起こしました)。

4

4 に答える 4

0

レガシーコードを使用している場合は、1つのインターフェイスを使用し、最初は1つの実装を使用して、データベースに関連する関数ごとにメソッドを追加します。たとえば、SaveOrderは、単純なクラス(Order :)などを取ります。または、データセットをプッシュします。すべてのSQLが実装に含まれ、それを使用するすべてのものがインターフェースを通過するまで、作業を進めながらさらに多くのものを追加します。

次に、別のデータベース、またはNoSQL、Xml、ORMなどの他の永続層に実装する場合は、何をする必要があるかがわかり、単体テストも一連あります。

于 2012-07-18T13:27:57.293 に答える
0
  1. ORMに近づかないでください。それらはプロジェクトでの目的を持っていますが、データベースの独立性だけが必要な場合は、ハンマーと釘だけが必要なときにGeneralFactoryFactoryを購入するようなものです。

  2. 一連のインターフェイスの背後にあるデータアクセス層を分離します。コードベースにはデータベースに依存するものはありませんが、これらのインターフェイスの実装です。したがって、これらの実装外のクラスは、クラスパスに「jdbc」、「jpa」、または「hibernate」が含まれるものにアクセスしないでください。JDependまたはDependencyFinderを使用して、実際のテストを作成することを検討してください。

  3. 現在のデータベースアクセスにこれらのインターフェイスを実装させます。

  4. 実際のデータベースに対して実行され、一連の異なるデータベースに対して実行する準備ができている自動テストを用意します。

  5. 2番目のデータベースをサポートする必要がある場合は、両方のデータベースに対して実行するようにテストを変更します。インターフェイスの実装を元の実装のコピーにしてから、失敗したテストを修正します。

  6. 次に、2つの実装を見て、抽出する価値のあるものを見つけ、それに応じてコードをリファクタリングします。

ステップ6をチェーンのさらに上に移動しようとすると、YAGNIとWrongAbstractionExceptionの悪いケースが発生します。

あらゆる種類のORMまたはその他のデータベースアクセステクノロジを使用する場合は、同じルールが適用されます。

于 2012-07-18T15:29:33.113 に答える
0

yuoが使用しているアプリケーションプラットフォームを指定していません。ただし、.NetまたはJavaのいずれかを使用していると思います。最初の防御策は、アプリケーションのSQLステートメントでODBCまたはJDBCエスケープシーケンスを使用し、このアプローチでは処理できないものをすべてストアドプロシージャにプッシュすることです。

アプリケーションのより徹底的なリファクタリングのライセンスをお持ちの場合は、アプリケーションプラットフォームのORMライブラリへの切り替えを検討する必要があります。

編集:Javaを使用していて、ORMライブラリへの切り替えがオプションではないことを明確にするために質問を編集したようです。かなり前に、私は大企業の顧客向けの製品の開発に取り組んでいました。各顧客は標準の参照アーキテクチャを使用していたため、Oracle、Microsoft SQL Server、およびUDB/DB2に対応する必要がありました。他のプラットフォームをサポートしていた可能性がありますが、一部の詳細は10〜12年後にあいまいになる傾向があります。これは、時間定数、関数、およびストアドプロシージャの呼び出しにJDBCエスケープを忠実に使用し、より機密性の高い操作をデータベース固有のストアドプロシージャにプッシュすることで実現しました。ですから、私の経験に基づいて、このアプローチが機能することをお伝えすることができます。現在、一連の買収を通じて、この製品はOracleミドルウェアポートフォリオの一部であるため、私は

私のもう1つの経験は、ビッグデータウェアハウジングプロジェクトでした。その場合、Oracle固有の機能を多用したため、別のデータベースプラットフォームに移行することはまったくできませんでした。

したがって、SQLServerを使用しているかどうかを評価することをお勧めします。特定の機能がアプリケーションに固有のものです。もしそうなら、あなたはただ別のプラットフォームに移動することは大規模な書き直しなしの選択肢ではないことを受け入れるべきです。そうでない場合でも、JDBCエスケープを使用してSQLを中心に機能を改善できるかどうかを確認してください。

于 2012-07-18T13:06:14.270 に答える
0

MyBatisフレームワークの使用を検討するかもしれません。MyBatisはSQLクエリと結果セットをJavaオブジェクトにマップし、DB固有のクエリ生成もサポートしています。既存のアプリケーションにドロップするのは非常に軽量であり、コードの総行数を大幅に削減できる可能性があります。機能を示す簡単なマッピングファイルの例については、ドキュメントのMulti-dbベンダーサポートに関するセクションを参照してください。

于 2012-07-18T14:02:39.850 に答える