ここまでのところで、 Postsモデルを説明するPHPで記述されたORMがあり、他のモデルとの中間テーブルを介して多対多の関係があることを想像してください : Comments、Tags、Categories 。 問題は、関連データを一度に、または遅延読み込みで上げる最適な方法は何ですか?
データベースコミュニティで一般的な意見は、多くのjoin'ovを使用して1回の要求でデータを取得する方が良いというものです。DBMSはスマートであると言います。 私の練習では、大きなテーブルを持つ高負荷のプロジェクトで、いくつかの単純なクエリが、複数の結合を持つ1つの大きなクエリよりも速く動作する場合がありました。
ORM側では、1回のリクエストですべてのデータを上げることも最適なオプションではありません。ほとんどの場合、この場所で必要のない追加のデータが上げられる(または干渉する可能性があり、それでもセットから削除する必要がある)か、セットが必要だからですfindWithComments、findWithCategoriesAndTags、findWithAllRelationsなどのメソッドは避けられない重複を伴います。
したがって、リンク(モデルメソッド)をロードするには3つの方法があります。
- 1つのリクエストですべてのデータを常に読み込む1つのfind($ id)メソッド。
- いくつかのメソッドfind($ id)、findWithComments($ id)、findWithTagsAndCategories($ id)...
- 現在のモデルのみをロードするfind($ id)メソッド+リンクをロードする明示的なメソッドgetComments()、getTags()...後者のメソッドは、単一のオブジェクトとオブジェクトのコレクション(Compositeに類似)の両方で同じように機能します。
ある種のユニバーサルORMの設計について話す場合、後者のオプションは私にとってより適切であると思われ、ORMは別のアプローチを許可すべきではありません。 メリットについてお話します。
- DBレベルでのキャッシュ。 データの小さなチャンクは、大きな固有の要求よりも頻繁に(異なる要求で再利用されるため)キャッシュから取得する必要があります。
- アプリケーションレベルのキャッシュ。 原則として、異なるテーブルからのデータは異なる減衰率を持ちます。最初の方法を使用する場合、最も迅速に無関係になるデータに集中する必要があります。 3番目の方法を使用する場合は、モデルごとに独自のキャッシュライフタイムを指定できます。これにより、(イベントまたは手動で)キャッシュをクリアするより柔軟な(モデルベースの)制御が可能になります。
- データ量またはクエリ数の増加に伴い、垂直データベースシャーディング用の既成のアーキテクチャがあります。
- いずれの場合も、必要なデータのみをダウンロードできます。
- たとえば、SQLとnoSQLを組み合わせて使用するための既製のアーキテクチャでは、一部のモデルをmongoまたはredisに転送し、このためにあらかじめ決められた数のメソッドを書き換えることができます。
このようなモデルの厳格な分離の弱点は、タグやカテゴリによる投稿など、多くの基準によって柔軟な検索をすぐに行う方法です。
一般的に、議論にあなたを招待します、他にどんな欠点がありますか、誰かがそのような決定から来た/行ったかもしれません、あなたはあなたのプロジェクトでそのようなORMを使用しますか?