PHP (Phalcon Framework) и MySQL: отношения моделей и JOIN

Например, есть 3 таблицы:

  • товары
  • product_images
  • product_specs

И в моделях этих 3 таблиц есть отношения один к одному.

Показывая 50 товаров на странице, вы получаете +2 дополнительных запроса внутри цикла, так что всего 150 строк и классный объект:

$products = Products::find();
foreach ($products as $product)
{
    $product->name;
    $product->images->filename;
    $product->specs->volume;
}

Или просто создайте собственный метод в модели продуктов и СОЕДИНИТЕ все необходимые таблицы:

$products = Products::getComplete();
foreach ($products as $product)
{
    $product->name;
    $product->imageFile;
    $product->specVolume;
}

Итак, мне интересно: полезна ли первая практика и не создает ли она большую нагрузку на демон MySQL или резко замедляет время выполнения php-скрипта?


person Jeckerson    schedule 13.01.2014    source источник


Ответы (1)


Ответьте на свой первый вопрос: эта практика может быть полезной, но это будет зависеть от вашей точной реализации.

Но вы правы. Использование встроенной связи «один к одному» будет запрашивать связанную модель каждый раз, когда на нее ссылаются, что является интенсивным. Так:

$products->images

— новый запрос для каждой записи.

К счастью, есть лучший и более эффективный способ достижения того же результата — PHQL.

Поскольку взаимно-однозначная таблица — это, по сути, объединенная таблица, которая вызывается через второй запрос (когда в этом действительно нет необходимости), вы можете выполнить то же самое, выполнив что-то вроде:

$products =
    (new \Phalcon\Mvc\Model)
        ->getModelsManager()
        ->executeQuery(
            "SELECT   products.*, product_images.*, product_specs.* ".
            "FROM     Products    AS products ".
            "JOIN     ProductImages AS product_images ".
            "ON       products.id = product_images.product_id ".
            "JOIN     ProductSpecs AS product_specs ".
            "ON       products.id = product_specs.product_id");

который выполнит только один запрос и даст вам ту же информацию, которую вы хотели раньше.

Это как раз один из тех случаев, когда вам нужно определить дорогостоящие запросы и выбрать альтернативный метод.

person brian    schedule 13.01.2014