|
|
|
| Сначала распишу ситуацию:
Пытаюсь продумать логику скрипта, похожего на магазин.
Планирую многоуровневую структуру категорий: подкатегории товаров будут вложены в родительские, которые, в свою очередь, будут так же вложены в своих родителей.
Количество уровней в разных категориях будет разной - где-то будет 3 уровня, где-то 2 или 4.
Товары планирую "отдавать" по, примерно, таким url:
example.com/maincat/cat/subcat/item.php
|
При выводе страницы товаров будет выводиться "Навигационная цепочка" (Навигационное меню, «Хлебные крошки», англ. Breadcrumbs).
Да и к тому же нужно как-то валидировать url - проверять, что бы, например, фотоаппараты открывались именно по url:
example.com/electronics/photo/digital-cameras/12345.php
|
не смотря на то, что мы можем просто взять из id товара из _GET и дернуть его из БД.
А если "дерево" категорий этого товара не совпадает с переданным в url - отдавать 404.
Далее:
В таблице с товарами есть поле, в котором хранится ID его категории и по этому полю идёт связь с таблицей категория.
Что бы мне вывести Breadcrumbs или для валидации url мне потребуется делать несколько быстрых не сложных запросов в БД, поднимаясь "вверх" до самой корневой "родительской" категории, выбирая их ID и названия.
Так вот к чему я это всё:
Мне пришла в голову мысль - а что если в таблице с товарами завести еще два поля, в которые сразу при добавлении товаров класть информацию о категориях, которая может мне пригодиться позже.
Например в одно "новое" поле мы кладем названия:
electronics/photo/digital-cameras
|
Во второе кладём id:
Вид этой информации не важен /пока/, можно даже и сериализованный массив.
Таким образом мы, дергая одним запросом из одной таблицы с товарами получаем информацию и о товаре и о дереве его категорий, которую потом можем использовать.
Т.е. увеличиваем размер данных, занимаемый товарами, но получаем несколько бонусов.
Мне, пока, видятся такие:
- уменьшение времени генерации страницы
- снижение нагрузки на mysql-сервер
- уменьшение дисковых операций
Вопрос:
Вы так делали / где-то встречали такое?
Стоит ли идти по этому пути? | |
|
|
|
|
|
|
|
для: an0n
(15.05.2013 в 19:03)
| | Уж тогда:
example.com/electronics/photo/digital-cameras/12345 - где 12345, это id конечного продукта (без всяких php, ЧПУ, так ЧПУ).
<?
$tree = array(
'electronics'=>123,
'photo'=>234,
'digital-cameras'=>345
);
$part = eplode('/', $url);
| О чем либо это говорит?
Писать на каждый товар путь не к чему, его всегда можно получить, и это не такая и трудоемкая работа. | |
|
|
|
|
|
|
|
для: confirm
(15.05.2013 в 19:17)
| | Да, скорее всего, ЧПУ так и будет выглядеть, вопрос не в этом.
А в том - есть ли целесообразность хранения в таблице с товарами информации о дереве категорий, что бы при выводе тех же "Breadcrumbs".
Пример: открыта страница с товаром:
example.com/categories/electronics/photo/digital-cameras/12345
|
На этой странице, необходимо вывести навигацию-breadcrumbs с таким html-кодом:
<span><a href="example.com/categories/">Категории</a></span>
->
<span><a href="example.com/categories/electronics/">Электроника</a></span>
->
<span><a href="example.com/categories/electronics/photo/">Фото</a></span>
->
<span><a href="example.com/categories/electronics/photo/digital-cameras/">Цифровые фотоаппараты</a></span>
|
Чтобы ее вывести на странице с товаром, мы
1) берем ID товара из _GET
2) делаем первый запрос в БД в таблицу товаров, вынимая нужные данные о товаре, в которых, помимо прочего, будет ID категории этого товара
3) делаем второй запрос в БД в таблицу категорий, вынимая
а) русское название этой категории (для вывода в анкоре ссылки)
б) английское название этой категории (для формирования url на эту категорию)
в) выбираем parent_ID
4) если parent_ID этой категории не равно нулю, т.е. если эта категория товара не является верхней, то делаем третий запрос в таблицу категорий, вынимая данные о родительской категории.
И так далее.
Т.е. чем глубже сидит товар в дереве категорий, тем больше запросов для выемки данных об этих категориях нам нужно сделать.
Поэтому я и подумал - что, если хранить данные о полном дереве категорий нашего товара прямо в таблице с товарами, то не придется делать sql-запросы, а нужно будет просто распарсить уже имеющуюся информацию.
Что думаете? | |
|
|
|
|
|
|
|
для: an0n
(15.05.2013 в 20:14)
| | Я же вам уже высказал свое мнение - нет, хранить для каждой записи путь к ней, это лишнее.
Вообще, если уж говорить о подходе вашем, то выгоднее иметь путь типа такого:
example.com/category/15/product/12345
где, category/15, это запрашивается категория товара с id равной 15, а product/12345, это запрос продукта этой категории с указанным id. Можно вообще сократить это, и тем не менее понимать, что запрашивается продукт определенной категории:
example.com//product/15/12345
В обеих вариантах, url содержит конечные значения, а не родителей и прадедушек. Это не значит, что нельзя описать весь путь в запросе, просто чем больше таковой, тем больше потребуется на разбор этого пути.
В случаях же указанных выше, ветвь навигатора указывающая положение на странице, это всего лишь один запрос к базе для получения этой ветви, естественно с получением имени категорий - если запрошен продукт, значит начиная от родителя этого продукта, если запрос категории продуктов (url либо не содержит ссылку на product, либо содержит один id), значит начиная с этой категории.
Но как бы вы не крутили, вам в любом случае потребуется проверка - есть ли запрашиваемый ресурс, так как магазин, это не только товары на страницах, это еще и корзина, оформление заказа, возможно отображение статуса заказа, и многое другое, а значит ваши url на все ресурсы должны строится по одному принципу, и обрабатываться по одним и тем же правилам. А кроме запроса действительно ресурса могут быть и ложные запросы.
Если вас страшат кучи запросов о ветвях дерева (что является неоправданным), ну кто вам запрещает единожды получить это дерево и хранить как массив в сессии, а уж проверить есть ли в таком массиве ресурс запрашиваемый, так это плевое дело. Ну а что касается "долгого" запроса о дереве, ветвях, то есть способ хранения дерева в базе, о котором не так часто говорят, но в нем есть очень выгодные моменты, можете использовать и это решение - NESTED SETS.
Ну и напоследок - любое программное решение, это автомат получающий на входе данные и обрабатывающий их по заданным условиям. Чем меньше условий, тем меньше время отклика автомата. Чтобы сократить условия автомату, входные данные должны иметь одну и туже структуру. При этом не важно будет какова длина их или сколько частей эти данные будут иметь, эта величина может быть динамически изменяемой.
То что описываете вы, это уже не автомат, это механический степлер сшивающий данные и работающий безупречно до определенной "толщины" их, стоит только выйти за пределы этой "толщины" - сломается. | |
|
|
|
|
|
|
|
для: confirm
(16.05.2013 в 07:19)
| | Я понимаю, что можно сделать как Вы говорите - это и проще и быстрее. Можно вообще информацию о категориях в URL не включать.
Спасибо за Ваш ответ, но у меня задача - настроить обработку именно вышеописанного вида URL. | |
|
|
|
|
|
|
|
для: an0n
(18.05.2013 в 00:31)
| | Да пожалуйста, надо, значит надо, пусть ваш URL хоть у Владивостока заканчивается. Я то не об этом отзываюсь как лишнее, а о путях, которые вы хотите держать для каждой записи.
Предположим, что мы решаем одну задачу - на вход устройства нужно подать данные, с условием, что это устройство должно понимать и производить определенные действия с ними в зависимости от их типа. Это цифры, буквы и ни то, и ни другое.
Я на входе устройства установил селектор, который определяет тип данных и сообщает конечному устройству об этом.
Вы обошлись без этого, и гоните данные на вход устройства напрямую, сортируя исключительно их вручную.
Стоит ли задавать вопрос, что ваш подход чреват большими неприятностями, если вы допустите ошибку. В моем же подходе такого просто не произойдет.
Вот в подходе "держать все и вся готовое на все", который вы описываете, скрывается мина замедленного действия.
С одной стороны хорошо - вытянул готовое, вставил. К тому же добавляется это готовое один раз, при добавлении записи.
Но почему вы упускаете из виду то, что ваши записи далеко не статичные - что-то будет удаляться, что-то перемещаться. Добавляя конфеты, вы решили, что коли из них можно и брагу делать, значит в вино-водочные, а завтра спохватились, что деток ни с чем оставили, и перенесли их в бакалею. А конфет то, от Гусиных лапок до изысканных шоколадных, и надо будет перелопачивать все. Да мало ли по каким причинам придется менять родителей, связи...
Стоит где-то упустить, допустить ошибку, и ваш путь к праху, и во многих местах это может сказаться (все зависит от связей, ссылок на них и т.д.).
А получать путь динамически нет проблем - берем только то, что есть по факту, от папы до пра-пра-дедушки. А если и был сбой тоже, так найти и устранить утечку на узком участке всегда легко, нежели копать траншею по всему проспекту, искать и латать дыры на всем протяжении.
Думайте. Но коли и это надо, и вроде бы не проблема для вас, делайте, тоже не запрещается. ) | |
|
|
|
|
|
|
|
для: confirm
(18.05.2013 в 01:38)
| | Да,согласен, поддерживать актуальность связей при рокировках в категориях будет проблематично.
Спасибо... | |
|
|
|
|