Объектно-реляционное отображение: каков наилучший способ реализации геттеров? - PullRequest
4 голосов
/ 04 октября 2008

Что должно произойти, когда я позвоню $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;
}

Мой основной вопрос: лучше ли минимизировать количество запросов к базе данных или лучше минимизировать объем данных, которые передаются из базы данных.

Другая возможность состоит в том, что лучше всего загружать атрибуты, которые вам понадобятся больше всего / содержат наименьшее количество данных при создании объекта и все остальное по требованию.

Следующий вопрос: что делают структуры абстракции ORM, такие как Activerecord?

Ответы [ 3 ]

9 голосов
/ 04 октября 2008

Там действительно нет правильного ответа на это. Зависит от того, сколько пользователей вы загружаете одновременно, сколько полей текста / блобов находится в вашей таблице пользователей, загружает ли ваша таблица пользователей какие-либо связанные дочерние объекты. Как говорит aaronjensen, этот шаблон называется отложенная загрузка - а противоположное поведение (загрузка всего впереди на всякий случай, если вам это нужно) известно как готовая загрузка,

Тем не менее, есть третий вариант, который вы можете рассмотреть, это ленивая загрузка всего объекта User при обращении к любому из его свойств:

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

Преимущества этого подхода состоят в том, что вы можете создать коллекцию пользователей (например, список всех пользователей, чьи пароли пустые, может быть?) На основе только их идентификаторов, без потери памяти при полной загрузке каждого отдельного пользователя, но затем вам требуется только один вызов базы данных для каждого пользователя, чтобы заполнить остальные поля пользователя.

6 голосов
/ 04 октября 2008

Минимизируйте количество запросов. Оптимальное количество запросов равно 0, но если вам нужно выполнить запрос, потому что он не кэширован, это 1. Запрос для каждого свойства - это верный путь к системе, которая никогда не масштабируется, имеет большие проблемы с конкуренцией и вызовет гораздо больше головной боли, чем его ценность.

Я должен отметить, что ленивая загрузка имеет значение (о чем вы говорите в шаге 1) , если , маловероятно, что вам понадобятся данные, загружаемые лениво. Хотя, если вы можете, лучше всего быть явным и получать точно или почти точно то, что вам нужно. Чем меньше времени вы тратите на запросы, тем меньше времени будет ваше соединение открыто и тем масштабнее будет ваша система.

0 голосов
/ 04 октября 2008

Я бы согласился с aaronjensen, за исключением случаев, когда объем данных, которые вы извлекаете, настолько велик, что вы начнете использовать чрезмерное количество памяти. Я думаю, где в строке есть 3 текстовых поля, которые все довольно большие, и все, что вам нужно, это поле ID.

...