Вопрос

Мне кажется, что этот вопрос уже задавался, наверное, тысячу раз, поэтому прошу прощения, если на него был дан ответ.И если да, может ли кто-нибудь указать мне правильные сообщения/ссылки?

Я пытаюсь создать многогранную навигацию для своего сайта.Он использует MySQL, и вот приблизительный набросок таблиц, которые я использую:

products:
- id
- title
- description
attributes:
- product_id
- name
- value
categories:
- id
- name
products_to_categories:
- product_id
- category_id

Я хочу отобразить список доступных атрибутов, когда вы находитесь в категории, что позволит вам выбрать одно или несколько значений для каждого из этих атрибутов.В качестве примера взгляните на эту страницу из Office Depot: http://www.officedepot.com/a/browse/binders/N=5+2177/

До сих пор я использовал множество объединений для фильтрации по нескольким атрибутам:

SELECT products.*, a_options.*
FROM products_to_categories AS pc, products,
attributes AS a_options,    /* list of attribute/value pairs I can continue to refine on */
attributes AS a_select1     /* first selected attribute */
attributes AS a_select2     /* second selected attribute */
...
WHERE pc.category_id = 1
AND products.id = pc.product_id
AND a_options.product_id = products.id
AND a_options.name != 'Color' AND a_options.name != 'Size'
AND a_select1.product_id = products.id
AND a_select1.name = 'Color' AND (a_select1.value = 'Blue' OR a_select1.value = 'Black')
AND a_select2.product_id = products.id
AND a_select2.name = 'Size' AND a_select2.value = '8.5 x 11'

По сути a_options вернет все атрибуты для тех продуктов, которые являются подмножеством фильтров, которые я применил с помощью a_select1 и a_select2.Поэтому, если я использую пример Binders из Office Depot, я хочу показать все доступные атрибуты после выбора «Синий» или «Черный» для цвета и «8,5 x 11» для размера.

Затем я использую PHP-код для удаления дубликатов и упорядочиваю полученные атрибуты в такой массив:

attributes[name1] = (val1, val2, val3, ...)
attributes[name2] = (val1, val2, val3, ...)

Есть ли способ ускорить мой запрос или написать его более эффективно?У меня есть установочные индексы по имени и значению в таблице атрибутов (а также по всем идентификационным номерам).Но если кто-то выберет пару атрибутов, запрос будет выполняться медленно.

Заранее благодарны за Вашу помощь,
Шридхар

Это было полезно?

Решение

«Затем я использую PHP-код для удаления дубликатов»

Тогда он не будет масштабироваться.

После того, как я прочитал http://www.amazon.com/Data-Warehouse-Toolkit-Techniques-Dimensional/dp/0471153370 Я безостановочно внедрял фасеты и механизмы фильтрации.

Основная идея заключается в использовании звездообразной схемы.

Вы создаете таблицу фактов, в которой хранятся факты.

customerid | dateregisteredid | datelastloginid
1 | 1 | 1
2 | 1 | 2

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

date_registered
Id | weekday | weeknumber | year | month | month_year | daymonth | daymonthyear
1 | Wed      | 2            | 2009 | 2   |2-2009      | 4        | 4-2-2009

Затем, какую бы «парадигму» даты вы ни использовали, возьмите все идентификаторы из этой таблицы измерений и

 select * from the fact table where the fact.dateregisteredid is IN( ... the ids from the date dimension table that represent your time period)

Эти «индексированные представления» ваших данных должны находиться в отдельной базе данных, а изменение производственного объекта должно помещать эту запись в очередь для повторного индексирования в системе аналитики.Крупные сайты могут группировать свои записи в непиковое время, поэтому приложение для создания статистических отчетов всегда отстает на несколько часов или дней.Я всегда стараюсь поддерживать его до второго, если архитектура это поддерживает.

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

Подводя итог, вы копируете данные и денормализуете их.Этот метод известен под названием «хранилище данных» или OLAP (обработка онлайн-аналитики).

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

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

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

Другие советы

Вы можете создать таблицу фасетов на основе нормализованных таблиц базы данных.
Например:

> SELECT * FROM product_facet
product_id | facet_type | facet_value
1          | color      | blue
2          | color      | blue
3          | color      | green
4          | color      | yellow
1          | speed      | slow
2          | speed      | slow

Затем просто выполните этот запрос, чтобы получить общее количество по атрибуту:

SELECT facet_type, facet_value, COUNT(facet_value) as total
FROM product_facet
GROUP BY facet_type, facet_value;

Результат:

facet_type | facet_value | total
color      | blue        | 2
color      | green       | 1
color      | yellow      | 1
speed      | slow        | 2

При поиске по критериям вы можете выбрать таблицу фасетов по идентификатору продукта:

SELECT facet_type, facet_value, COUNT(facet_value) as total
FROM product_facet
WHERE product_id in (SELECT product_id FROM products WHERE ... )
GROUP BY facet_type, facet_value;
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top