2009-08-28 2 views
8

私は不動産業者のプロジェクトに取り組んでいます。私は以下のオブジェクト/ MySQLテーブルをデザインに持っています:PHP/MySQL OOP:SQLから複雑なオブジェクトをロード

これは上記のオブジェクト間の関係です。

Complexes have a single Agent. 
Complexes have multiple Units, Amenities, Pictures, Links, Documents, and Events. 
Units have multiple Pictures, Links, and Documents. 

設備、写真、リンク、ドキュメント、およびイベントはすべて、データベースに必要な外部キーは、彼らが属するユニット/複雑指定する必要があります。

データベースからPHPに必要なオブジェクトをロードして、プロジェクトで使用できるようにする必要があります。

LEFT JOINSを使用して、1つのクエリでテーブルからすべてのデータを選択しようとすると、各リンクのATLAST(リンク数)*(画像数)*(文書数)ユニークなユニット。アメニティやイベントを追加してみましょう。*コンビニエンスの数*各コンプレックスのイベント数... PHPのオブジェクトにロードすることに対処しようとしていますか。

I適切にインデックスのすべての私の場合:

他の可能性は次のように私の質問があり、リンク、写真、ドキュメントに対して各1つの個別のSQL文を実行し、各複合/ユニット用でのイベントや

の設備しますテーブルは、各複合体/ユニットに対して3-5の追加クエリを実行することは本当に悪い考えですか?

もしそうでなければ、私はPHPオブジェクトにロードする必要があるデータをどのように取得できますか?

Unit Object 
(
    [id] 
    [mls_number] 
    [type] 
    [retail_price] 
    [investor_price] 
    [quantity] 
    [beds] 
    [baths] 
    [square_feet] 
    [description] 
    [featured] 
    [year_built] 
    [has_garage] 
    [stories] 
    [other_features] 
    [investor_notes] 
    [tour_link] 
    [complex] => Complex Object 
     (
      [id] 
      [name] 
      [description] 
      etc. 
     ) 
    [agent] => Agent Object 
     (
      [id] 
      [first_name] 
      [last_name] 
      [email] 
      [phone] 
      [phone2] 
      etc. 

     ) 
    [pictures] => Array 
     (
      [1] => Picture Object 
       (
       ) 
     ) 
    [links] => Array 
     (
      [1] => Link Object 
       (
       ) 
     ) 
    [documents] => Array 
     (
      [1] => Document Object 
       (
       ) 
     )  
) 

私はいつもこの情報のすべてを必要としない、時々私は時々私は唯一の主キーを必要とする、複雑なの主キーを必要とする、:単位のために、次のように理想的には、私は、オブジェクトを持っているでしょう私はそれをインスタンス化するたびにオブジェクト全体をロードすることになります。

私はOO PHPに関する多くの研究を行ってきましたが、ほとんどの(すべてを読んで)オンラインの例では1つのテーブルしか使用していません。それは私が取り組んでいるプロジェクトが多くの複雑な関係を持っているので、明らかに役に立たない。何か案は?私は完全にここのマークオフですか?

おかげ

[UPDATE]

一方は、通常、誰もが表示されますフロントエンド、上、私はすべての情報が必要になります。たとえば、特定のコンプレックスに関する情報が必要な場合は、そのコンプレックスに属するすべてのユニット、すべての画像、ドキュメント、リンク、コンプレックスのイベント、ユニットのすべての画像、ドキュメント、リンクを表示する必要があります。

私が避けたいのは、1ページの読み込み中に、1つのクエリを実行して必要な複合体を取得することでした。次に、複合体に関連付けられた20単位を取得する別のクエリ。次に、20台のユニットのそれぞれについて、画像のための質問の実行、文書のための他の質問、リンクのための他の質問などを行いました。

[編集2] また、画像、ドキュメント、リンク、イベント、エージェントをデータベースから選択するためのクエリは非常に簡単です。ちょうど基本的なSELECT [列のリスト] FROM [テーブル] WHERE [primary_key] = [値]と時折INNER JOIN。私は複雑な計算やサブクエリはしていません。基本的なものです。

[ベンチマーク] 私の質問に対するすべての回答を読んだ後、私は自分の決めたことについてベンチマークを実行することに決めました。私がやることは、私が必要とするすべてのユニットをロードすることです。その後、私は絵を表示する必要があるので、その時にドキュメントを読み込みます。私は3万のテストユニットを作りました。それぞれに100枚の写真、100のドキュメント、100のリンクがありました。その後、ユニット数を読み込み(1000、次に100、より現実的な10)、ループしてユニットに関連付けられたすべての画像、ドキュメント、リンクをロードしました。 1000台で約30秒かかりました。 100台で約3秒かかりました。 10台で約0.5秒かかった。結果には多くの違いがありました。場合によっては、10単位で、12秒かかることもあります。その後、それは0.8を要するだろう。その後、おそらく.5。その後.78。それは本当にすべての場所でした。しかし、それは約0.5秒間平均していたようです。実際には、一度に6台しか必要ではないかもしれませんが、それぞれ10枚の写真、5つのリンク、5枚のドキュメントが関連付けられているかもしれません...だから、「必要なときにデータを取得する」アプローチはこのような状況で最善の策だ。このすべてのデータを一度に取得する必要がある場合は、必要なすべてのデータをロードするための単一のSQL文を用意して、データを1回だけループさせるようにしてください(1回に6700ユニットに217秒かかりました30,000人のPHPがメモリ不足になりました)。

答えて

4

すべてのテーブルのインデックスを正しく作成しても、各コンプレックス/ユニットに対して3-5個の追加クエリを実行することは本当に悪い考えですか?

つまり、関連するテーブルごとに、おそらく別のクエリを実行する必要があります。これが、ほとんどのORM(オブジェクト・リレーショナル・マッピング/モデリング)システムが行うことです。

パフォーマンスが実際に問題になっているとしたら、それはそうではありません。その場合、APC、memcache、Xcacheなどの方法で結果をキャッシュすることを検討してください。

0

ORMのポイントは、毎回オブジェクト全体を読み込まないことです。ポイントは、あなたのアプリがオブジェクトにアクセスするのを簡単かつ透過的にすることです。

と言われています。ユニットオブジェクトが必要な場合は、ユニットオブジェクトとユニットオブジェクトのみを読み込みます。エージェントオブジェクトが必要な場合は、ユニットオブジェクトをロードするときではなく、必要に応じてエージェントオブジェクトをロードします。

+0

最大の問題は、管理セクションでは、これらの部分が細かく管理できるように分割されていることです。あなたがあなたのデータにアクセスすることがありますので、しかし、フロントエンドには、1ページが – SpaDusA

+0

...すべてのそれはユニット、関連するすべての画像、文書、イベント、およびリンクだけでなく、割り当てられたエージェントの情報を連絡し、複雑な表示されますインデックス付きの列を介して実際にすべてを使用すると、これは問題ではありません。私の答えはORMがそう言われたので、すべてのデータを取り戻す方向に向いていました。 – longneck

0

多分あなたはこれを壊すことを考えるべきです。

オブジェクトを開始するときに、そのオブジェクトが機能するために必要な詳細だけを取得します。より多くの詳細が必要な場合は、移動して入手してください。ロードと処理はこのようにして行います。オブジェクトはロードと処理が必要な処理のみを取得し、それ以上の処理が必要な場合は取得します。

あなたの例では、最初に複合体を作成します。あなたがユニットにアクセスする必要がある場合には、その後、私のように自分のMVCフレームワークをでっち上げたときに、私はしばらく前にこの問題に対処しなければならなかったなど

$complexDetails = array('id' => $id, etc); 
$complexUnits = array(); 
......... 
$complexUnits[] = new unit(); 
......... 
$complexDetails['agent'] = new Agent(); 
0

、あなたはエージェントを必要とするとき、そのエージェントを取得し、そのユニットを作成します実験。 DBからロードされたデータのレイヤーを制限するために、コンストラクターに整数を渡しました。各コンストラクタは、インスタンス化されたオブジェクトのコンストラクタに渡す前にこの整数をデクリメントします。 0になると、それ以上サブオブジェクトがインスタンス化されません。これは、基本的に、渡されたintはロードされたレイヤの数を意味しました。

私は唯一のユニットオブジェクトの属性を望んでいたのであれば、私はこれを行うだろう:あなたは「ストア」オブジェクトをしたい場合は、単にPHPの配列にロードし、キャッシュにそれらを意味し、

 
$myUnit = new Unit($unitId,1); 
0

をそれを直列化します。その後、データベース、memcache、または他の場所に保存することができます。ラベルを付けると、そのラベルを取得でき、タイムスタンプが含まれているので、どれくらい古いかを知ることができます(つまり、リフレッシュする必要があります)。

データが変更されない場合、または変更頻度の低い、実際に複数の複雑なクエリを毎回実行する理由はありません。単純なものは、プライマリを取得するように、データベースに直接ヒットすることもできます。

+0

私はオブジェクトを格納したくないと思います。私が理解しようとしているのは、データベース内の情報をPHPで効率的に読み込む方法です。 – SpaDusA

関連する問題