複雑なSQLを処理したい時に、Propelを活用する知恵 | 金の知恵 開発者ブログ

金の知恵 開発者ブログ

金の知恵は、あなたの知恵の価値を測る無料のモバイルサイトです。

サル知恵は0点!?さて、あなたの知恵は何点?

こんにちは、システム担当の林です。
暦上はまだ2月の前半ですが、今日の東京はポカポカと春を感じさせるような気候ですね。
いよいよ寒い季節が終わるなぁ~と思いつつも、一方でいよいよ花粉の季節だなぁ・・・と思ったりもする今日この頃です(^_^;)


さて、今日は久しぶりに?技術の話題に戻って、symfonyが採用しているORマッパ、Propel(および、抽象化DBレイヤーCreole)の話を。

Propelは、データベースへのアクセスを、SQLを直接書かずに実現できるので
つまらないSQLの文法ミスとかが無くなるので、その点では非常にありがたいのですが
一方で、例えばサブクエリを使うような、複雑なSQLを使いたい時にはちょっと悩ましかったりもします。
Propel/Creoleの方でも、直接SQLクエリを記述するやり方もあるのですが
それだとせっかく「SQLを書かなくて済む」というメリットが意味がなくなってしまうので
極力Propel/Creoleに仕事をまかせるための知恵を書きます。

ま、そんなたいそうなことじゃなく、わかってしまえばな~んだ、ということなんですが、
データベースにVIEWを作成して、複雑なSQLの部分をVIEWに閉じ込めてしまえばいいのです。
(なお、MySQLの場合は、VIEWが使用できるのはMySQL5.0以降になります)

基本的な考え方としては、FROM句に対してサブクエリを使用したい場合は
そのままサブクエリ部分をVIEW定義にすればOK。

WHERE句内でサブクエリを使用する場合は、
サブクエリ部をJOINに変更して、VIEWをうまく定義してあげます。

そして、VIEW定義したものを、schema.ymlに記述してあげればOK。
Propelから見た場合、参照先がテーブルかビューかは基本的に関係ないので
テーブルを定義する時と全く同じ要領で記述できます。

もっとも、サブクエリに記述する内容によっては、そんなに簡単にいかないことも多々あります。
特に相関サブクエリや自己結合のJOINを使うようなケースは難しいかもしれません。

また、使用するデータベースによっては、更新系のSQLがビューに対して使えなかったりするので
そのあたりも注意が必要です。

もう1点、ビューを使うことで、パフォーマンスが落ちる可能性があります。
実際どの程度パフォーマンスが落ちるかは、
DB設計やビュー定義、データ件数などいろいろな要素に影響を受けるので、
EXPLAINなどを使って分析し、使用する・しないの判断をするべきかと思います。

VIEWの使用が許容できるのであれば、ORマッパを素直に利用することができるケースが多いので
SQLを直接埋め込む前に検討する価値はあるのではないかと思います。


それでは。