方法1:カウントする
質問に対して即座に返ってきた方法としては、スクリプトでひたすらカウントするというものです。つまり新市町村の数が欲しいのに旧市町村の数がわからないためにごちゃごちゃになっているわけで、DBからフェッチする際に両方の数をカウントしていき適宜記憶しておくという方法です。
前述の例でもう少し具体的に書くと、新市町村のデータが10件欲しい場合1ページ目では旧市町村は28件あります。フェッチする際にどちらもカウントしていき新市町村の数が10を超えるところで止めて、その時の旧市町村の数(= 28)を記憶しておきます。次に2ページ目のデータが欲しい時には記憶しておいた28の次からデータを取得するようにして、つまりLIMITのoffset値を28からにしてデータを取得する、というものです。
まあやりたいことを素直に実装する?というのか力技?というのか、質問しておいて某氏には申し訳ありませんが、自分はあまり気に入りませんでした(^^;
問題点はまず旧市町村の数を記憶すると書きましたが、いったいどこに記憶するんだ?というところで、FORMのhiddenフィールドなりURL埋め込みなりとにかくどこかに保持しておいて次のリクエスト時に送ってもらわないとなりません。
それにこの方法だとLIMITのoffset値はわかりますが実はlimit値の方をどのくらいに設定しておけばいいのかが定かではありません。LIMIT 28, 10 では明らかに足りないことは明白ですし、かといってLIMIT 28, 30 ぐらいに適当に増やしておいて〜みたいな方法もなんとなく最初に大きめに取得しておいて後からその中の必要な部分を取ってくる的感が強くてどうもしっくりきません。
で、結局この方法は却下されたわけですが、某氏はこの方法を一通り説明し終った後にポロっと「本当は最初に新市町村の方のデータだけを取ってきて、次に旧市町村のデータを取ってくるようにするのがいいんだよね」みたいなことを言われました。ということで…
方法2:SQLを多発する
まず新市町村のデータをページあたり10件欲しいならそれを取ってきます。次にそのデータを元に関連している旧市町村のデータを順次取ってきます。あとはそれを出力して終了!
これもまあ力技?といえばいえなくもないような…スクリプト側の処理は方法1の「記憶する」みたいな部分もなく、冗長な?データも取得せずに済みますが、その代わり?というかSQLを投げまくらないといけません。
この例の場合だと最初に新市町村のデータを取得するときで1回、ページあたり10件なら旧市町村のデータを取得するのに10回、それと全件数も必要ですから1回、計12回のSELECTを投げることになります。
某氏によればDBが別ストレージ?とかにあるような場合でなければ特に問題ないだろうとのことでしたが、自分的にはやはり投げすぎじゃない?という感がひとしおでした。ページあたり10件なら上述のように12回のSELECTで済みますがこれが20件とか100件とかなっていくとなんだかなぁ…と。
ちなみに後にCakePHPのActiveRecordでHABTMのアソシエーションを張ったデータを取得してみたら12回SELECTが投げられていました(--; 汎用的に作ろうとするとどうしてもそうなるのかな?いずれにしてもSQL多発ってところで自分的には却下されました。
そして解決策のないまま本当に旅に出ることに…
ラベル:PHP