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

StackOverflow https://stackoverflow.com/questions/169818

  •  05-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top