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;
}

我的基本问题是是否最好尽量减少数据库查询的数量,或者是否最好尽量减少从数据库传输的数据量。

另一种可能性是,最好在创建对象时加载您最需要的属性/包含最少的数据,并按需加载其他所有内容。

一个后续问题:像 Activerecord 这样的 ORM 抽象框架是做什么的?

4

3 回答 3

9

这个真的没有正确答案。取决于您一次加载的用户数量、用户表中有多少文本/blob 字段、用户表是否加载任何关联的子对象。正如 aaronjensen 所说,这种模式称为延迟加载- 而相反的行为(预先加载所有内容以备不时之需)称为急切加载

也就是说,您可能需要考虑第三种选择,即在访问 User 对象的任何属性时延迟加载整个 User 对象:

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

这种方法的优点是您可以仅根据他们的 ID 创建一个用户集合(例如,密码为空的所有用户的列表,也许?),而无需完全加载每个用户的内存命中,但您只需要每个用户的单个数据库调用以填充其余用户字段。

于 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 回答