Архитектура БД для фильтров аналог Яндекс Маркета?

Разрабатываем сейчас структуру характеристик товара, чтобы реализовать фильтры как на Яндекс Маркете.

Высоконагрузный проект, поэтому запросы на 5 листов А4 не пойдут.

market.yandex.ru/guru.xml?cmd=-rr=9,0,0,0-v…


Вот смотрите, если отмечаем любой пункт в фильтре, то вся фильтрация перестраивается и убираються те пункты, по которым подбор уже не пройдет
my.jetscreenshot.com/5783/20110219-smd2-59k...

И это все летает


Вопрос, может есть где статьи или человек, который сможет построить архитектуру таблиц с такими фильтрами?

Готов хорошо заплатить
  • Вопрос задан
  • 8467 просмотров
Пригласить эксперта
Ответы на вопрос 4
Делали нечто подобное (фильтр по 100-120 чекбоксам и около 50 других вариаций (селекты, диапазоны))
Чекбоксы загнали в одно 128 битное число — уже съэкономили кучу времени
часть диапазонов (цена от 100-200 200-500 500-1000 и т.д.) так же преобразовали в маленькие числа и объединили в другими показателями. Получился Индекс размером в 300-350 байт. Из него сделали 128 битный «md5» И «поисковой таблице» было всего лишь id, наш Индекс + id товара +128 битный md5. Выборка делается по 128 битному числу (ясно дело, что часть товаров туда попадают не те, которые нужно (процентов 5 максимум)), потом из выборки в 100-300 товаров делается проверка по полному Индексу (первая выборка с мемтаблицу делается). На выходе то, что нам надо.
На деле еще реализован алгоритм нечеткого поиска, что бы при ограничении в максимальной цене в 200$ показывать товар и за 220-230 (+-10-15%).
Товаров в базе около 12 млн (детали станков, автозапчасти и т.п.).
Поисковая таблица на пару порядков меньше в размере, чем исходная. Поиск идет за считанные миллисекунды.
Ответ написан
coxx
@coxx
Вам стоит использовать Sphinx. Посмотрите доклад про организацию товарного каталога в dostavka.ru. Sphinx также используется в товарном каталоге на gorbushka.ru.
Ответ написан
archibaldtelepov
@archibaldtelepov
А чем не устраивает стандартное реляционное решение вида

product (product_id [PK], name,… );
property (property_id [PK], name, ...);
value (value_id [PK], value);
product_property_value (product_id, property_id, value_id, primary key (property_id, value_id, product_id, ));

или есть какие-то данные, которые показывают, что на ваших объёмах оно будет тормозить?

на одном интернет-проекте на 250 000 активного ассортимента и 60 000 уникальных посетителей в сутки не тормозит особо.
Ответ написан
archibaldtelepov
@archibaldtelepov
Да, конечно.

начну с конца. value — чтобы выбирать по числовому идентификатору и чтобы для свойства «цвет крышки» хранился номер 100, а не где-то слово «белый», а где-то «белий» ну и т.п.

далее, в интерфейсе подбора по параметрам человек выбирает «а покажите мне все продукты, у которых объём жесткого диска 2 гб, а ширина экрана 100 метров».

выбираем продукты

select distinct p.name,p.code,p.price from
product p inner join product_property_value ppv using (product_id)
where
ppv.property_id = HDD_SIZE_PROPERTY_ID and value_id = VID_100GB
and ppv.property_id = SCREEN_SIZE_PROPERTY_ID and value_id = VID_100M


при наличии индекса ppv(property_id, value_id) должно работать быстро

тут, конечно, возникает разумный вопрос — а что делать с запросами типа «ширина монитора больше 17 дюймов».

на что возникает резонный ответ — если у нас есть такие запросы, у нас есть несколько вариантов:

1) не париться, и добавлять в приведённый выше запрос таблицу value, для которой построен индекс по полю value

select distinct p.name,p.code,p.price from
product p inner join product_property_value ppv using (product_id)
inner join value v on v.value_id = ppv.value_id
where
ppv.property_id = SCREEN_SIZE_PROPERTY_ID and v.value > VID_17IN


2) делить таблицу value на, скажем, три

value_int для целых значений
value_string для текстовых
value_decimal для нецелых значений

в таблицу property мы добавляем признак типа значений свойства и на этапе построения приведённого выше запроса соединяем с требуемой таблицей

из всего этого видим мы, что основная проблема — это выборки по диапазонам, так?
а выборки по одному или нескольким значениям нормально решаются с помощью value_id

3) следующий способ оптимизации по скорости:
для всех значений, для которых возможна выборка по диапазону
мы добавляем в property поля
max_value_id и min_value_id
указывающие на идентификатор ряда в value, в котором хранится максимальное и минимальное значение свойства соответственно.

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

при использовании такого подхода можно выбирать с помощью конструкции value_id between даже при поиске по диапазону значений и не лазать в таблицу value при выборках, что добро
Ответ написан
Ваш ответ на вопрос

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

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