20

オブジェクト リレーショナル マッピングについては、こちらを含め、よく議論されています。私はいくつかのアプローチと、落とし穴と妥協の経験があります。真の解決には、オブジェクト指向またはリレーショナル モデル自体の変更が必要なようです。

関数型言語を使用している場合、同じ問題が発生しますか? これら 2 つのパラダイムは、OO と RDBMS よりもうまく適合するはずです。RDBMS のセットで考えるという考え方は、関数型アプローチが約束しているように見える自動並列処理と噛み合っているようです。

興味深い意見や洞察を持っている人はいますか? 業界のプレイ状況は?

4

7 に答える 7

11

リレーショナル データベースを拡張する際の難しい問題は、トランザクションの拡張、データ型の不一致、クエリの自動変換、N+1 Selectのようなものであり、リレーショナル システムを離れる基本的な問題であり、私の意見では、プログラミングパラダイムを受け取ります。

于 2008-10-20T13:14:13.273 に答える
7

それはあなたのニーズに依存します

  1. データ構造に集中したい場合は、JPA/Hibernate のような ORM を使用してください
  2. 処理方法を明らかにしたい場合は、FRM ライブラリを参照してください: QueryDSL または Jooq
  3. SQL リクエストを特定のデータベースに合わせて調整する必要がある場合は、JDBC とネイティブ SQL リクエストを使用してください

さまざまな「リレーショナル マッピング」テクノロジの強みは移植性です。アプリケーションがほとんどの ACID データベースで確実に実行されるようにします。そうしないと、手動で SQL リクエストを作成するときに、さまざまな SQL 方言の違いに対処することになります。

もちろん、SQL92 標準に拘束することもできます (そして、関数型プログラミングを行うこともできます)。ORM フレームワークで関数型プログラミングの概念を再利用することもできます。

ORM の強みは、ボトルネックとして機能する可能性のあるセッション オブジェクトに基づいて構築されています。

  1. 基になるデータベース トランザクションが実行されている限り、オブジェクトのライフサイクルを管理します。
  2. Java オブジェクトとデータベース行の間の 1 対 1 のマッピングを維持します (また、オブジェクトの重複を避けるために内部キャッシュを使用します)。
  3. 関連付けの更新と削除する孤立したオブジェクトを自動的に検出します
  4. 楽観的ロックまたは悲観的ロックで並行性の問題を処理します。

それにもかかわらず、その長所は短所でもあります。

  1. セッションはオブジェクトを比較できる必要があるため、equals/hashCode メソッドを実装する必要があります。ただし、オブジェクトの等価性は、データベース ID ではなく「ビジネス キー」に基づいている必要があります (新しい一時オブジェクトにはデータベース ID がありません!)。ただし、一部の具体化された概念には、ビジネスの平等がありません (たとえば、操作)。一般的な回避策は、データベース管理者を混乱させる傾向がある GUID に依存しています。

  2. セッションは関係の変更をスパイする必要がありますが、そのマッピング ルールにより、ビジネス アルゴリズムに不適切なコレクションの使用がプッシュされます。HashMap を使用したい場合がありますが、ORM では、キーが別の軽量オブジェクトではなく別の「リッチ ドメイン オブジェクト」である必要があります...次に、キーとして機能するリッチ ドメイン オブジェクトにオブジェクトの等価性を実装する必要があります...しかし、このオブジェクトにはビジネスの世界に対応するものがないため、それはできません。そのため、反復する必要がある単純なリストに戻ります (パフォーマンスの問題が発生します)。

  3. ORM API は、実際の使用には適さない場合があります。たとえば、実際の Web アプリケーションは、データをフェッチするときに「WHERE」句を追加してセッション分離を強制しようとします...その場合、「Session.get(id)」では不十分で、より複雑な DSL ( HSQL、Criteria API) またはネイティブ SQL に戻る

  4. データベース オブジェクトは、他のフレームワーク専用の他のオブジェクトと競合します (OXM フレームワーク = オブジェクト/XML マッピングなど)。たとえば、REST サービスが jackson ライブラリを使用してビジネス オブジェクトをシリアル化するとします。しかし、この Jackson は Hibernate One に正確に対応しています。次に、両方をマージして、API とデータベース間の強い結合が表示されるか、翻訳を実装する必要があり、ORM から保存したすべてのコードがそこで失われます...

一方、FRM は、"オブジェクト リレーショナル マッピング" (ORM) とネイティブ SQL クエリ (JDBC を使用) の間のトレードオフです。

FRM と ORM の違いを説明する最善の方法は、DDD アプローチを採用することです。

  • オブジェクト リレーショナル マッピングは、データベース トランザクション中に状態が変更可能な Java クラスである「リッチ ドメイン オブジェクト」の使用を強化します。
  • ファンクショナル リレーショナル マッピングは、不変の「貧弱なドメイン オブジェクト」に依存しています (コンテンツを変更するたびに、新しいオブジェクトを複製する必要があります)。

ORM セッションに課せられた制約を解放し、ほとんどの時間を SQL よりも DSL に依存しています (したがって、移植性は問題ではありません)。しかし、一方で、トランザクションの詳細、同時実行の問題を調べる必要があります。

List<Person> persons = queryFactory.selectFrom(person)
  .where(
    person.firstName.eq("John"),
    person.lastName.eq("Doe"))
  .fetch();
于 2016-07-01T10:03:46.367 に答える
3

サムが述べたように、DBを更新する必要がある場合は、OOの世界と同じ並行性の問題に直面する必要があると思います。プログラムの機能的な性質は、RDBMSのデータ、トランザクションなどの状態のために、オブジェクトの性質よりも少し問題になる可能性があります。

しかし、読むために、関数型言語はいくつかの問題のあるドメインでより自然である可能性があります(DBに関係なくそうであるように思われるため)

機能的な<->RDBMSマッピングは、OO<->RDMBSマッピングと大きな違いはありません。しかし、それは、まったく新しいDBスキーマを使用してプログラムを開発したり、従来のDBスキーマに対して何かを実行したりする場合など、使用するデータ型の種類に大きく依存すると思います。

たとえば、関連付けの遅延フェッチなどは、遅延評価関連の概念を使用して非常にうまく実装できます。(OOでも非常にうまく実行できますが)

編集:グーグルでHaskellDB(Haskell用のSQLライブラリ)を見つけました-試してみる価値はありますか?

于 2008-10-20T12:27:50.840 に答える
3

関数関係マッピング自体は行っていませんが、関数型プログラミング手法を使用して RDBMS へのアクセスを高速化しました。

データセットから開始し、複雑な計算を行い、結果を保存することは非常に一般的です。たとえば、結果は元のサブセットに追加の値を加えたものです。命令型のアプローチでは、最初のデータセットを追加の NULL 列とともに保存し、計算を行ってから、計算された値でレコードを更新する必要があります。

合理的なようです。しかし、それに関する問題は、非常に遅くなる可能性があることです。更新クエリ自体以外に別の SQL ステートメントが計算に必要な場合、またはアプリケーション コードで実行する必要がある場合は、計算後に変更するレコードを文字通り (再) 検索して、結果を正しい行に格納する必要があります。 .

結果用の新しいテーブルを作成するだけで、これを回避できます。このようにして、更新の代わりに常に挿入することができます。キーを複製して別のテーブルを作成することになりますが、NULL を格納する列でスペースを無駄にする必要はなくなります。次に、結果を最終選択に結合します。

私はこのように RDBMS を (ab) 使用し、最終的に次のような SQL ステートメントを作成しました...

create table temp_foo_1 as select ...;
create table temp_foo_2 as select ...;
...
create table foo_results as
  select * from temp_foo_n inner join temp_foo_1 ... inner join temp_foo_2 ...;

これが本質的に行っていることは、一連の不変バインディングを作成することです。ただし、良い点は、セット全体を一度に作業できることです。Matlab のような行列を操作できる言語を思い出すようなものです。

これにより、並列処理もはるかに簡単になると思います。

特別な利点は、この方法で作成されたテーブルの列のタイプを指定する必要がないことです。これは、それらが選択された列から推測されるためです。

于 2008-10-20T18:46:34.210 に答える
3

機能からリレーショナルへのマッピングは、OO から RDBMS へのマッピングよりも簡単に作成および使用できると思います。データベースにのみクエリを実行する限り、そうです。副作用なしで良い方法でデータベースの更新を行う方法が (まだ) よくわかりません。

私が見る主な問題はパフォーマンスです。現在の RDMS は、機能的なクエリで使用するようには設計されておらず、かなりの数のケースで適切に動作しない可能性があります。

于 2008-10-20T12:09:43.170 に答える