4

を呼び出すとどうなります$user->get_email_address()か?

オプション 1: オンデマンドでデータベースから電子メール アドレスを取得する

public function get_email_address() {
    if (!$this->email_address) {
        $this->read_from_database('email_address');
    }
    return $this->email_address;
}

オプション 2: オブジェクトの作成時にデータベースから電子メール アドレス (およびその他のユーザー属性) を取得する

public function __construct(..., $id = 0) {
    if ($id) {
        $this->load_all_data_from_db($id);
    }
}

public function get_email_address() {
    return $this->email_address;
}

私の基本的な質問は、データベース クエリの数を最小限に抑えるのが最善か、それともデータベースから転送されるデータの量を最小限に抑えるのが最善かということです。

もう 1 つの可能性は、オブジェクトの作成時に最も必要な属性をロードし、必要に応じて他のすべてのデータを含めることが最善であるということです。

フォローアップの質問: Activerecord のような ORM 抽象化フレームワークは何をしますか?

4

3 に答える 3

9

これには本当に正解はありません。一度にロードするユーザーの数、ユーザー テーブルに含まれるテキスト/ブロブ フィールドの数、ユーザー テーブルが関連する子オブジェクトをロードするかどうかによって異なります。aaronjensen が言うように、このパターンは遅延読み込みと呼ばれ、反対の動作 (必要な場合に備えてすべてを事前に読み込む) は熱心な読み込みとして知られてます

そうは言っても、考慮したい 3 番目のオプションがあります。これは、プロパティのいずれかにアクセスしたときに User オブジェクト全体を遅延読み込みすることです。

public function get_email_address() {
    if (!$this->email_address) {
        $this->load_all_data_from_db($this->id)
    }
    return $this->email_address;
}

このアプローチの利点は、ID のみに基づいてユーザーのコレクション (たとえば、パスワードが空白のすべてのユーザーのリストなど) を作成できることです。すべてのユーザーを完全にロードするためのメモリ ヒットは必要ありませんが、必要なのはユーザーごとに 1 回のデータベース呼び出しで、残りのユーザー フィールドにデータを入力します。

于 2008-10-04T07:33:28.223 に答える
6

クエリの数を最小限に抑えます。クエリの最適な数は 0 ですが、キャッシュされていないためにクエリを実行する必要がある場合は 1 です。すべてのプロパティに対してクエリを実行することは、決してスケーリングされず、大規模な競合の問題があり、より多くの頭痛の種を引き起こすシステムへの確実な方法です。それは価値があります。

遅延ロードされるデータが必要になる可能性が低い場合は、遅延ロード (これはステップ 1 で話していることです) の価値があることに言及する必要があります。ただし、可能であれば、明示的に指定して、必要なものを正確またはほぼ正確に取得することをお勧めします。クエリに費やす時間が短いほど、接続が開いている時間が短くなり、システムのスケーラビリティが向上します。

于 2008-10-04T05:44:42.233 に答える
0

私は aaronjensen に同意します。ただし、取得するデータの量が多すぎてメモリを大量に使い始める場合を除きます。行に 3 つのテキスト フィールドがあり、すべてが非常に大きく、必要なのは ID フィールドだけだと考えています。

于 2008-10-04T06:02:56.567 に答える