skillup

技術ブログ

Database

joinとeager loading

投稿日:

フレームワークでデータをORMがらみでjoinするときのネタ。

自分の場合はLaravel。他のフレームワークでも考え方は通じるものあるかと・・

通常のjoin

select句に何も指定せずjoin句を使うとプロパティがフラットになってしまいます。これだとカラム名が競合した時に片方が消されてしまいます。

例えばorderからorderitemをjoinしようと思った時にorderの1プロパティの中にorderitemがあり、この中にorderitemの全てのプロパティがあるというのが理想的です。

ループの中で取得

親(order)の数×子供の数(orderitem)となってしまい計算量的にありえないのでNG。

hasManyなどを動的に使用

https://readouble.com/laravel/5.1/ja/eloquent-relationships.html

上記のようなリレーションを動的に組む方法がベストっぽいです。これだと親のレコードの中にプロパティとして格納されるため、通常のjoinと違ってカラムが消されたりってことはありません。

ただこの手法だとjoin自体が実行されるのは親自体(order)をループする時になり、DBへのアクセス数が親の数×子供の数となってしまいます。(これが俗にいうN+1問題と言われるものらしいです。)

通常の取得をlazy loadingというようですね。

ちなみにディフォルトでhasManyなどのjoin関係を定義しておくと、親が絡む全てのSQLで自動的に子供がついてきてしまい、非常にめんどくなりますので、動的にリレーションの関係は作るようにしましょう。

eager loading

これを解決するのがeager loadingという手法のようでクエリを発行した瞬間にDBへのアクセスも終わります。

こうすることで

  • 親のプロパティの中に子供のオブジェクトを格納し、
  • かつ計算量も抑える

ということができます。

えらい単純なことですが、これに行きつくまでにそこそこ時間がかかりました・・・(汗)

参考リンク

laravelじゃないですが、参考になりそう。

CakePHP3のORMを使う際に欠かせない概念について

-Database
-

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

no image

データベース設計のアンチパターン 重すぎるOLTP+Date型不統一+データ量想定が甘い

Contents1 重すぎるOLTP1.1 デメリット1.2 対策2 DATE型の型の不統一2.1 デメリット2.2 対策3 データ量の想定が甘い3.1 デメリット3.2 対策 重すぎるOLTP ※O …

no image

MySQLでのlocalhostと127.0.0.1の違い

たまにMySQLでローカルのホストに接続する時に、localhostで接続するときと127.0.0.1で接続するときで挙動が違う(片方だとエラーになり、もう片方だとエラーにならない)などがあるのでちょ …

no image

データベースの権限設定

データベースを作成するときに

と入力していますが、ほぼ機械的にこれを売っているのでこれを機にどんな使い方があるのかを調べてみました。 …

no image

データ構造の基礎知識 後編 木構造

データベースの学習をしていたときの復習です。 データ構造の基礎知識 前編 メモリとポインタ、配列と連結リスト データ構造の基礎知識 中編 ハッシュ 今回はもう少し複雑な「木構造」について考えてみます。 …

no image

JavaでのSQLの書き方

ちょっと小ネタです。 通常SQLを記述する場合、縦に分けて書くのが見た目にも見やすく、保守性も高いです。 例として

と書くよりは、 [ …