Как правильно реализовать каталог с параметрическим поиском

Beavis

Banned
Именно поэтому древовидная монга, при всех своих недостатках, гораздо лучше отображает в виртуальности такое понятие реальной жизни, как "каталог товаров"
Т.е. получается в проекте надо использовать 2 СУБД: монго для каталога, mysql - для всего остального?
а такие сущности как "товары" и "заказы" в какой базе хранить?
и как связывать всё это друг с другом?
 

Фанат

oncle terrible
Команда форума
Т.е. получается в проекте надо использовать 2 СУБД: монго для каталога, mysql - для всего остального?
Не обязательно. Некоторые вообще все в монге хранят.
Хотя лично я бы использовал две, да.
и как связывать всё это друг с другом?
так же, как и в случае с чисто мускулевым решением - по первичному ключу.
Скажем, в документе монго с определенной моделью телефона хранить список айдишников новостей из мускулевской таблицы, привязанных к этой модели.
 

craz

Нестандартное звание
почему ты все время повторяешь эту денормализацию, как заклинание? что ты конкретно имеешь ввиду? Для решения какой конкретной задачи тебе нужна денормализация? Какие конкретно данные собрался денормализовывать?
К примеру, мы разрабатываем форум. Традиционный путь ассоциировать пользователя с его постом — это колонка userid в таблице posts. с такой моделью нельзя отобразить список постов без дополнительного извлечения данных (JOIN) из таблицы пользователей. Возможное решение — хранить имя пользователя (name) вместе с userid для каждого поста. Можно также вставлять небольшой встроенный документ, например, user: {id: ObjectId('Something'), name: 'Leto'}. Да, если позволить пользователям изменять своё имя, нам придётся обновлять каждый документ (пост) — это один лишний запрос.

Ты эту модель в действии видел? можешь сейчас привести код, который выводит все характеристики определенного телефона? Сколько SQL запросов тебе для этого понадобится?
Мне глубоко параллельно, кем ты меня считаешь, но мне подсказывает опыт, что если есть легковесные таблицы связей, и одна таблица хранящая все-все, проще работать будет с первым вариантом.
отличный пункт.
Лично ты за Sphinx как я понял
 

Gas

может по одной?
порылся в структуре базы одного из старых проектов, итого:

чтоб получить все характеристики объекта (одного или несколько), действительно нужнен не 1 запрос, а 2. Второй чтоб подтянуть значения из "мультисправочников", то-есть справочников, из которых товару может быть прикреплено несколько свойств.
например, "Поддерживаемые стандарты сети" - gsm 900, gsm 1800, gsm 1900 (в примере реальных данных ниже, клиент почему-то не сделал такой вариант справочником, но это уже не ко мне вопрос)

Код:
select SQL_NO_CACHE pg.title as `group`, p.title as prop, p.`type` as prop_type, pev.value as prop_list_value, pp.*
from catalog_products_properties as pp 
join catalog_properties as p on p.id=pp.id_property
join catalog_properties_groups as pg on pg.id=p.id_property_group
left join catalog_properties_enum_groups as peg on peg.id=p.id_list
left join catalog_properties_enum_values as pev on pev.id=pp.value_numeric and pev.id_enum_category=p.id_list
where pp.id_product=XXX;

96 rows in set (0.01 sec)
+ второй запрос по таблице catalog_properties_enum_values по primary key (второй запрос делается потому, что ссылки на multi-values хранятся в сериализованном виде, здравствуй лень матушка)

+ цикл который из общей портянки формирует более удобоваримую структуру.

Код:
mysql> explain select SQL_NO_CACHE pg.title as `group`, p.title as prop, p.`type` as prop_type, pev.value as prop_list_value, pp.* from catalog_products_properties as pp  join catalog_properties as p on p.id=pp.id_property join catalog_properties_groups as pg on pg.id=p.id_property_group left join catalog_properties_enum_groups as peg on peg.id=p.id_list left join catalog_properties_enum_values as pev on pev.id=pp.value_numeric and pev.id_enum_category=p.id_list where pp.id_product=6316177;
+----+-------------+-------+--------+---------------------------+------------+---------+------------------------------------+------+-------------+
| id | select_type | table | type   | possible_keys             | key        | key_len | ref                                | rows | Extra       |
+----+-------------+-------+--------+---------------------------+------------+---------+------------------------------------+------+-------------+
|  1 | SIMPLE      | pp    | ref    | id_property,id_product    | id_product | 4       | const                              |  118 |             |
|  1 | SIMPLE      | p     | eq_ref | PRIMARY,id_property_group | PRIMARY    | 4       | pp.id_property                     |    1 | Using where |
|  1 | SIMPLE      | pg    | eq_ref | PRIMARY                   | PRIMARY    | 4       | p.id_property_group                |    1 | Using where |
|  1 | SIMPLE      | peg   | eq_ref | id                        | id         | 4       | p.id_list                          |    1 | Using index |
|  1 | SIMPLE      | pev   | eq_ref | id,id_enum_category       | id         | 4       | pp.value_numeric                   |    1 |             |
+----+-------------+-------+--------+---------------------------+------------+---------+------------------------------------+------+-------------+
5 rows in set (0.01 sec)

mysql> select count(*) from catalog_products_properties;
+----------+
| count(*) |
+----------+
|  3660261 |
+----------+

mysql> select count(*) from catalog_properties;
+----------+
| count(*) |
+----------+
|     2632 |
+----------+

mysql> select count(*) from catalog_properties_groups;
+----------+
| count(*) |
+----------+
|      296 |
+----------+

mysql> select count(*) from catalog_properties_enum_groups;
+----------+
| count(*) |
+----------+
|      266 |
+----------+

mysql> select count(*) from catalog_properties_enum_values;
+----------+
| count(*) |
+----------+
|     2240 |
+----------+
Ещё раз, я не аггитирую за eav, просто привёл пример личного использования. Во время разработки сего дела mongo ещё не было.
 

Вложения

  • Like
Реакции: craz

fixxxer

К.О.
Партнер клуба
Это все хорошо, а теперь пожалуйста поиск по параметрам и сортировочку.
 
  • Like
Реакции: craz

fixxxer

К.О.
Партнер клуба
Вообще говоря, документная реплика в монге намного более естественна, чем плоские реплики в сфинксе с генерацией индексов под каждый сет параметров (то есть условно категорию).
Сфинкс он вообще не для того предназначен, и в подобных целях юзается не от хорошей жизни - а просто потому что умеет группировку-сортировку на лету (умел бы это мыскль - можно было бы и create table просто делать, код-то примерно тот же будет). Монга это тоже умеет, если я не ошибаюсь, и при этом совершенно естественна для произвольных наборов key-value.
Можно конечно и хранить все только в монге, но я бы зассал =)
 

Yoskaldyr

"Спамер"
Партнер клуба
Монга хорошая вещь, но все хранить в ней - однозначно не стоит
во первых очень большой перерасход железных ресурсов, во вторых всетаки мускуль по стабильнее и по предсказуемее будет. У монги начинаются очень интересные приколы на больших объемах (хотя бы от 500К документов) с относительно большим количеством составных индексов. Да и монго пхп клиент не такой стабильный как для других языков.
 

fixxxer

К.О.
Партнер клуба
Ну то есть как только все перестает влазить в оперативку начинается ЖОПА. Ну это предсказуемо совершенно, было бы странно если бы не.
 

Yoskaldyr

"Спамер"
Партнер клуба
Ну то есть как только все перестает влазить в оперативку начинается ЖОПА. Ну это предсказуемо совершенно, было бы странно если бы не.
Ну монга все-таки не in-memory DB. и такого поведения как у нее сейчас не должно быть.
Проблемы связаны с утечками памяти или с внутренними фичами монги, если это запланированное разработчиками поведение, - со временем монга начинает занимать все больше и больше оперативы, после чего падает с ошибкой (не хватает даже 32 гиг, учитывая что база + журналы + индексы в сумме 16 гиг)
Монга переваривает любые объемы, но если используются самые простые индексы и их немного.
 

Gas

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

Yoskaldyr

"Спамер"
Партнер клуба
Yoskaldyr
интересная инфа, а какая версия монги? вроде они с каждым релизом достаточно сильно улучшаю.
во всех, начиная с 2.0 (а может и раньше)
Т.е. монга очень специфический продукт может работать норм, а могут быть и косяки.
 

WMix

герр M:)ller
Партнер клуба
боже как много всего понаписанно...
есть продукты, они на столько различные и кровати и рутеры и крема и и и... продукт в каждой категории имеет кучу аттрибутов, скорость процессара, скорость высыхания, размеры, вес, шерсть или хлопок, и тд... если собрать это в единную таблицу как велит релационная база будет тысячи полей и большинство из них наль... нужен антипатерн...

пойск? да как с куста... покажи комьпьтеры (это категория) теперь сузим пойск, мы знаем список всех аттрибутов и можем искать только эппл или пентиум, или с минимальной памятью в 5 гигов... у краватей только железные, у продуктов только биологические и тд... смысл в другом

делайте на монго...
 
Сверху