@mix_gorbachev

Вопрос реструкторизации базы или правильно написанного запроса?

29487fbac0fa428f892574c1d4379fa1.JPG
Есть таблица товаров.
Есть те параметры, которые товар может иметь в количестве нескольких штук. К примеру область применения.

Возникла надобность фильтрации товара. По определенным параметрам, то есть нужно использовать 2-3 параметра из самого товара, плюс которые находятся во внешних таблицах

Данные по фильтрации хранятся в таких же таблицах
fde1707eb22f4599b699b1fadf48749a.JPG
в этих id_product является номером категории id_cut параметры по которым надо фильтровать.
Набросал код, но понимаю, что есть пробелы:
1. Если хоть одна категория отсутсвует условия не выполняться.
в общем я немного в ступоре.
SELECT t1.id
FROM
  `oboi_category_stily`,
  `oboi_category_oblasty_primeneniya`,
  `oboi_category_osobennosty`,
  `oboi_category_dlya`,
  `oboi_category_risunok(dizayn)`,
  `oboi_tovar_stily`,
  `oboi_tovar_oblasty_primeneniya`,
  `oboi_tovar_osobennosty`,
  `oboi_tovar_oboi_dlya`,
  `oboi_tovar_risunok(dizayn)`,
  oboi_tovar as t1
WHERE
  t1.material IN (SELECT id_cut
                  FROM `oboi_category_material`
                  WHERE id_product = 1) AND
  t1.tip IN (SELECT id_cut
             FROM `oboi_category_tip`
             WHERE id_product = 1) AND
  t1.vid_izdeliya IN (SELECT id_cut
                      FROM `oboi_category_vid_izdeliya`
                      WHERE id_product = 1) AND

  `oboi_category_stily`.id_cut = `oboi_tovar_stily`.id_cut AND
  `oboi_category_oblasty_primeneniya`.id_cut = `oboi_tovar_oblasty_primeneniya`.id_cut AND
  `oboi_category_osobennosty`.id_cut = `oboi_tovar_osobennosty`.id_cut AND
  `oboi_category_dlya`.id_cut = `oboi_tovar_oboi_dlya`.id_cut AND
  `oboi_category_risunok(dizayn)`.id_cut = `oboi_tovar_risunok(dizayn)`.id_cut AND

  `oboi_tovar_stily`.id_product = t1.id AND
  `oboi_tovar_oblasty_primeneniya`.id_product = t1.id AND
  `oboi_tovar_osobennosty`.id_product = t1.id AND
  `oboi_tovar_oboi_dlya`.id_product = t1.id AND
  `oboi_tovar_risunok(dizayn)`.id_product = t1.id AND

  `oboi_tovar_stily`.id_cut = 1 AND
  `oboi_tovar_oblasty_primeneniya`.id_cut = 1 AND
  `oboi_tovar_osobennosty`.id_cut = 1 AND
  `oboi_tovar_oboi_dlya`.id_cut = 1 AND
  `oboi_tovar_risunok(dizayn)`.id_cut = 1

Укажите направление, как доделать выборку, то чего то в голову вообще не приходят, на что смотреть
  • Вопрос задан
  • 213 просмотров
Пригласить эксперта
Ответы на вопрос 2
@ynblpb_spb
дятел php
Какая жесть у вас написана.
Для начала то, что вы селектите подряд таблицы - это внутри mysql является inner join. Вам же нужен left join. Тогда, если записи в таблице нету товар все равно будет выбираться.

Дальше общий вид запроса будет таким:
SELECT t.* FROM tovar
LEFT JOIN svyazka1 as s1 ON (s1.id_from_tovar = t.id)
LEFT JOIN svyazka2 as s2 ON (s2.id_from_tovar = t.id)
/* .. еще join при необходимости.. */
WHERE 
s1.category_id = 1 /* ID искомой категории внутри связки */
AND 
s2.category_id = 2 /* ID искомой категории внутри связки */


но в этом запросе есть одно НО. Сюда не приджойнить названия категорий, по которым идет поиск (а нужно ли?). Тут два варианта.
  • Отдельными мелкими запросами выбирать названия категорий для товара (не оч хорошо, но некритично, таблицы обычно маленькие со списком категорий).
  • Создать дополнительное поле в таблице с товарами, в которой хранить "кеш" (json/serialized) списка категорий и их ID, чтобы быстро их вывести, не обращаясь в БД. В этом случае дополнительная сложность - при изменении таблицы категорий придется пересобирать кеш в таблице товаров. и вообще следить за его актуальностью
Ответ написан
@dmitryKovalskiy
программист средней руки
Позвольте предположить? Половина указанных полей в таблице tovar (а то и 3/4) допускают значение null и для каждого товара - полей со значением null хватает.
С точки зрения архитектуры базы и ее нормальных форм - я бы их прибил поскорее.
Я думаю что здесь нужна таблица properties с полями - prop_id, category_id, isNull(обязательно или нет) и еще что-нибудь подобное. И еще одна таблица properties_value с полями tovarId, propId, value. Увеличивается количество JOIN-ов, но таблицы становятся проще и чище.

А сам запрос - треш, который быстрее сжечь и написать заново чем править.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы