Задать вопрос
@eliastro

Как организовать хранение товаров-замен для оптимизации поиска?

Добрый день!
Есть элементы (товары), которые могут быть тождественными заменами друг для друга. Например, есть товар А, для него есть замены В и С. При поиске А должны выводиться его замены - В и С. Далее для товара В могут установлены замены D и E. При поиске А должны тогда выводиться B,C,D,E. Все замены тождественно равны друг для друга. Соответственно, при поиске C должны вывестись A,B,D,E.
Сейчас хранение замен организовано таблицей с 2 полями.
A - B
A - C
B - E
B - D.
Текущий алгоритм поиска сводится к рекурсивному выполнению поисковых запросов к БД. Например, для А вначале ищутся его замены. Затем для найденных замен ищутся их замены и тд. Затем все объединяется и выводится итоговый результат поиска. Это очень неоптимально, т.к. по каждой найденной замене делается еще запрос и тд. Т.е. куча запросов, а нужно получить нужные данные одним запросом.
Пробовали денормализацию данных, т.е. хранить все комбинации:
А - В
А - С
А - Е
А - D
B - A
B - C
B- D
B -E
C -A
...
Но тогда таблица разрастается до огромных размеров - сотни миллионов строк (в наших условиях). Плюс еще проблема, если удалить связь замены, например, между A и B, тогда получается E и D тоже перестают быть заменами для А и С, как их тогда убрать эти связи в денормализованной таблице не понятно.
  • Вопрос задан
  • 267 просмотров
Подписаться 1 Оценить Комментировать
Решения вопроса 1
valerium
@valerium
Изобретая велосипед
Если замены двунаправлены независимо от уровня, то есть (по приведённому Вами примеру) A является заменой для E, то можно просто ввести ещё одно поле, которое будет одинаковым для всех товаров в одной группе замены. Что-то вроде связи многие-к-одному, но без дополнительной таблицы. Хотя никто не мешает ввести и дополнительную таблицу, чтобы дать имя группе замены.

Ну и, само собой, индекс по этому дополнительному полю.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Rsa97
@Rsa97
Для правильного вопроса надо знать половину ответа
Тут надо смотреть, насколько часто меняется список замен. Если не часто, то держать две таблицы - основной набор, как у Вас сейчас, и кэшированный список вида ('A' - 'B,C,D,E'), перестраивая его при изменении основного набора.
Ответ написан
Комментировать
sim3x
@sim3x
Но тогда таблица разрастается до огромных размеров - сотни миллионов строк (в наших условиях).
и прекрасно. Все равно там только три инта хранится, не так ли?

При денормализации придется повесить на update любого товара тригер, который обновит закешированное значение.
При удалении товара, перелопатит все товары, в которых данный товар является заменителем
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Похожие вопросы