Сделайте количество запросов постоянным с отношением многие ко многим - PullRequest
0 голосов
/ 27 мая 2018

У меня есть сущность, которая имеет 2 отношения «многие ко многим»:Существует Product, который может иметь много категорий и много тегов.A Tag или Category также может иметь много продуктов.Схема прямо сейчас:

products
-------------
product_id
name

categories
-------------
category_id
name

tags
-------------
tag_id
name

products_categories
-------------
product_id
category_id

products_tags
-------------
product_id
tag_id

Мне нужно отобразить на одной странице список товаров со всеми их тегами и категориями.Проблема в том, что количество выполняемых мной запросов равно 2n + 1, где n - количество продуктов, перечисленных на странице.Сначала я делаю:

select product_id, name from products

Затем в цикле в моем приложении я выполняю следующие запросы (в псевдокоде):

tags = []
categories = []
for each product
    tags[product_id] = select t.tag_id, t.name 
                       from products_tags as pt 
                       join tags t 
                           on pt.tag_id = t.tag_id
                       where pt.product_id = {product_id}

    categories[product_id] = select c.category_id, c.name 
                             from products_categories as pc 
                             join categories c 
                                 on pc.category = c.category_id
                             where pc.product_id = {product_id}
end for each

Есть ли хороший подход, чтобы число выполненных запросов не зависело от количества запрашиваемых записей? Редактировать Для каждого продукта мне нужно отобразить данные в этом формате:

-------------------------------------------------------
| Product name: A good smartphone                     |
| Categories: Tech, Smartphone                        |
| Tags: smartphone, some-smartphone-brand, 4g         |
|                                                     |
-------------------------------------------------------   

Ответы [ 2 ]

0 голосов
/ 28 мая 2018

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

select p.product_id, p.name, t.tag_id, t.name tag_name, c.category_id, c.cat_name 
from product p
join products_tags as pt on pt.product_id = p.product_id
join tags t on pt.tag_id = t.tag_id
join products_categories as pc on pc.product_id = p.product_id
join categories c on pc.category = c.category_id
order by p.product_id

Псевдокод


products = []
tags = []
categories = []
var productObj= {};
var product_id =false;
for each product
    /**
    * If product_id != product.id from loop iteration it means this is different product from previous iteration, Push this product object in `products[]`
    */
    if(product.id != product_id){
        products[product.id] = product;
        product_id = product.id;
    }
    /** you can put additional check here before insert in array if value is not present  `products[product.id][tags]` */
    products[product.id][tags][] = tag_name;

    /** you can put additional check here before insert in array if value is not present  `products[product.id][categories]` */ 
    products[product.id][categories][]= cat_name;
end for each

Пример объекта / структура данных для продуктов

[ 
    1 => [
    name => A good smartphone,
    categories => [Tech, Smartphone],
    tags => [smartphone, some-smartphone-brand, 4g]
    ],  
    2 => [
    name: Another product,
    categories => [Cat1, Cat2],
    tags => [Tag1, Tag2, .....]
    ],
.....
]
0 голосов
/ 27 мая 2018

Вы можете попробовать это (он поочередно использует соединение с тегами и категориями и различает их по столбцу table_type):

select *, 'CAT' as table_type
from products p left join products_categories pc left join categories c  
ON p.product_id = pc.product_id and pc.category_id = c.category_id
UNION ALL
select *, 'TAG' as table_type
from products p left join products_tags pt left join tags t  
ON p.product_id = pt.product_id and pt.tag_id = t.tag_id
order by p.product_id 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...