За последние 24 часа нас посетили 16406 программистов и 1558 роботов. Сейчас ищут 1746 программистов ...

Хранение товарной позиции в нескольких категориях

Тема в разделе "PHP и базы данных", создана пользователем tarpedo, 29 окт 2008.

  1. tarpedo

    tarpedo Активный пользователь

    С нами с:
    29 окт 2008
    Сообщения:
    6
    Симпатии:
    0
    Уважаемые форумчане.

    Прошу помочь советом как при помощи PHP + mySQL организовать хранение товара, статьи одновременно в нескольких категориях, разделах.

    Тоесть интерисует как организовать хранение в БД и корректно делать выборку при помощи PHP.

    Покажите хоть на пальцах.... Дальше сам расшарю.... :wink:
     
  2. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    tarpedo
    Очевидный выход - вводить вспомогательную таблицу, для связи "товар-категория".
    Но я обычно стараюсь этого избегать, чтобы не усложнять запросы, особенно когда "мультикатегорийных" товаров немного, а также когда у товара есть понятие основной категории. В этих случаях удобнее хранить прямо несколько копий товара в таблице (последователей решений по учебникам прошу не пинать), при изменении одной копии обновляя все.
     
  3. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    id_category в табл. с публикциями сделать строкой и хранить id категорий через запятую, выборку делать с помощью оператора IN
    зы. не пробовал так делать
     
  4. dAllonE

    dAllonE Guest

    Mr.M.I.T., думаешь будет производительнее чем с отдельной таблицей связкой?

    P.S. А разве IN так работает? Вроде как в этом случае только LIKE да и то гемор будет...
     
  5. tarpedo

    tarpedo Активный пользователь

    С нами с:
    29 окт 2008
    Сообщения:
    6
    Симпатии:
    0
    я такое просто видел в Data Life Engine, в нем можно одну новоть добавить в неограниченое количество категой. Может кто знает как там, а то если че поставлю гляну...
     
  6. QQQ

    QQQ Активный пользователь

    С нами с:
    21 ноя 2007
    Сообщения:
    538
    Симпатии:
    0
    скорее всего
     
  7. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    вот сам не знаю, не пробовал, вообще должен ИМХО
     
  8. karakh

    karakh Активный пользователь

    С нами с:
    11 дек 2007
    Сообщения:
    1.344
    Симпатии:
    0
    Почему только Like? Может регекспы или fulltextsearch?
     
  9. QQQ

    QQQ Активный пользователь

    С нами с:
    21 ноя 2007
    Сообщения:
    538
    Симпатии:
    0
    Mr.M.I.T.
    IN работает так:
    Код (Text):
    1.  
    2. SELECT * FROM table WHERE id = 1 OR id = 2 OR id = 8
    3. ===
    4. SELECT * FROM table WHERE id IN (1, 2, 8)
     
  10. tarpedo

    tarpedo Активный пользователь

    С нами с:
    29 окт 2008
    Сообщения:
    6
    Симпатии:
    0
    я думаю что IN тут никак не прокати так как я буду хранить данные не о том какие товары лежат в категории, а в каких категориях лежит товар. тоесть у каждого товара будет список категорий в которых он должен находится, а не у категории список товаров, хотя это все относительно и лишь влияет на способ выборки.
     
  11. tarpedo

    tarpedo Активный пользователь

    С нами с:
    29 окт 2008
    Сообщения:
    6
    Симпатии:
    0
    чуть позже попробую это изобразить в виде схем и выставить для критики.
     
  12. dAllonE

    dAllonE Guest

    Mr.M.I.T., был уверен что не работает, на всякий случай даже проверил сейчас - не воркает.


    karakh, LIKE был приведен чисто в качестве примера.
    Все эти регэкспы полнотекстовые поиски и LIKE юзать для данной цели ИМХО совершенно непроизводительно.


    tarpedo, я бы предпочел отдельную табличку для связки - товар/категория.
     
  13. QQQ

    QQQ Активный пользователь

    С нами с:
    21 ноя 2007
    Сообщения:
    538
    Симпатии:
    0
    tarpedo
    тебе предлагают как вариант - хранить список id категорий в строковом поле базы через запятую.. можно ещё массив категорий серилизовать.. но ИМХО это всё ужасно и как выборку делать - хз..

    нужно:
     
  14. tarpedo

    tarpedo Активный пользователь

    С нами с:
    29 окт 2008
    Сообщения:
    6
    Симпатии:
    0
    да, именно так наверно и поступлю, надо будет токо это дело потестить...
     
  15. lexa

    lexa Активный пользователь

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    Именно там организовано так, как было организовано у меня до того, как я начал знакомится с MySQL - через жопу.

    Есть список категорий (таблица categories), есть список постов (таблица news). При записи поста в news в поле category пишутся id категорий через запятую. Например: 1,3,12. Внимание, ща будет пипец. А ищется через оператор regexp:
    [sql]select * from news where category regexp '[[:<:]](1|8|66)[[:>:]]'[/sql]
    Ищет посты с категорией 1, 8 или 66.

    regexp очень долгий. Замена на более быстрый like ни к чему хорошему не привведёт. Во-первых, like тоже долгий. Во-вторых, он более тупой и помимо верных результатов отдаст ещё и всякую белеберду.

    Тебе нужно делать так. Помимо таблицы news и catergories завести news_categories, т.е. таблицу связи с двумя полями - news_id (тут будут id постов) и category_id (id категорий привязаных к постам). Это связь называется много-ко-многим (many-to-many). Есть ещё один-к-одному и много-к-одному. Последний это обратный вариант первого. Одна группа, но много пользователей. Много пользователей, но одна группа.

    Выборку дкелать так:
    [sql]select * from news
    left join news_categories on (news_id = news.id)
    left join categories on (categories.id = category_id)
    where а тут основной фильтр, например news.title = 'Пенисы. Президенты. Нефть. Что общего?'[/sql]

    P.S. То, что предлагает Dagdamor по умолчанию тупость. Почему тупость - это изложено в первой часте поста. Оно тебе не надо, ибо ты пользоваться не умеешь, а коли так любой твой косяк приведёт к жутким тормозам и неоправданым нагрузкам на базу данных. Dagdamor использует только, если связей мало и он умеет это использовать. Ты же пользуй много-ко-многим, стандартное, из учебника и немного скушное.
     
  16. dAllonE

    dAllonE Guest

    lexa, круто сказал. Ты случайно не преподаешь в универе? ;)
     
  17. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    lexa
    Эй, эй, полегче там. У тебя обострение, что ли?
    Если кто-то не умеет "этим" пользоваться - это еще не тупость, точнее тупость, но отнюдь не автора. Я подчеркнул, что этот способ хорош для случаев, когда среди 10000 товаров, каждый из которых в одной категории, есть с десяток товаров-исключений, лежащих в двух-трех категориях. Были у меня такие проекты, когда заводить лишнюю таблицу и автоматически гробить производительность (ведь оптимизация для сортировки и пейджинга накрывается медным тазом) - смысла не было.

    Э-э-э... а при чем тут первая часть поста? Там у тебя про LIKE и регэкспы. Я вообще о другом говорил, читай внимательнее.
     
  18. tarpedo

    tarpedo Активный пользователь

    С нами с:
    29 окт 2008
    Сообщения:
    6
    Симпатии:
    0
    а если допустим уже нет товаров, только категории с описанием - типичный пример многоуровневого пошагового FAQ.

    Тога задача значительно упращается так как надо только таблица с самим содержимым и индексная.

    В последней будут хнанится id родителей - тех страниц которым принадлежит текущая страница

    Как в таком случае поступить с упорядочиванием...
     
  19. lexa

    lexa Активный пользователь

    С нами с:
    22 июл 2007
    Сообщения:
    1.746
    Симпатии:
    0
    Адрес:
    Санкт-Петербург
    dAllonE, не, это просто потому что люблю выпендриваться. :)

    Dagdamor, я написал и про то и про другое, прочти внимательно. В том посте я про тебя ничего дурного не сказал (скажу в этом). Что ты писал не про like и regexp это я действительно попутал. У тебя ещё более тупая схема, чем было у меня с regexp. Ты её называешь много-ко-много-через-жопу? :) Можно изголяться с количеством полей category_id для связей, но дублировать товары, которые различные лишь категорией это полная маразмашка.

    tarpedo, я не очень понял суть второго вопроса. Обычно, такая штука назвается дерево. У тебя у категории есть id и есть pid (id категории родителя). Это стандартный метод, но есть и иные. И ты строишь по ним дерево.

    Например:
    id / имя / pid
    1 / Первая / 0
    2 / Вторая / 0
    3 / Третья / 1
    4 / Четвёртая / 1

    Получается:
    - Первая
    -- Третья
    -- Четвёртая
    - Вторая
     
  20. Kreker

    Kreker Старожил

    С нами с:
    8 апр 2007
    Сообщения:
    5.433
    Симпатии:
    0
    Самый простой и примитивный, ограничивающий действия, способ построить дерево:
    1 Категория 1
    1-1 Категория 1, папка 1
    1-2 Категория 1, папка 2
    2-1 Категория 2, папка 1
    2-1-1 Категория 1, папка 1, подпапка 1

    [sql]
    mysql> SELECT * FROM tst;
    +----+-------+
    | id | sort |
    +----+-------+
    | 1 | 2 |
    | 2 | 1 |
    | 3 | 1-1 |
    | 4 | 2-1 |
    | 5 | 2-2 |
    | 6 | 1-1-1 |
    | 7 | 1-2 |
    | 8 | 1-2-1 |
    | 9 | 1-2-2 |
    | 10 | 3 |
    +----+-------+
    [/sql]
    [sql]
    mysql> SELECT * FROM tst ORDER BY `sort`;
    +----+-------+
    | id | sort |
    +----+-------+
    | 2 | 1 |
    | 3 | 1-1 |
    | 6 | 1-1-1 |
    | 7 | 1-2 |
    | 8 | 1-2-1 |
    | 9 | 1-2-2 |
    | 1 | 2 |
    | 4 | 2-1 |
    | 5 | 2-2 |
    | 10 | 3 |
    +----+-------+
    10 rows in set (0.00 sec)
    [/sql]
    Но такой способ скорее для комментариев годится...
     
  21. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    lexa
    Для особо резвых на суждения и определения поясняю еще раз: если вы чего-то не понимаете, либо чем-то никогда не пользовались, либо не понимаете, как это работает - это не повод называть это "полной маразмашкой". Я так понял, ты таким методом никогда не пользовался. А я пользовался. У него единственный практический минус - это обновление (редактирование) товара, операция чуть сложнее, чем в других методах, грубо говоря "сложнее" на один запрос, но часто ли эта операция должна выполняться! Операции выборки - простые и быстрые, никаких лишних таблиц, никаких джойнов, все, включая сортировку и разделение на страницы, опирается на индексы. Никаких потерянных товаров. Никаких проблем с переносом товаров из категории в категорию. Расход памяти? Не смеши меня, ты думаешь, с дополнительной таблицей ты сэкономишь больше? Так что вполне нормальный подход, для многих ситуаций он годится прекрасно. Ну а уж как его называть - это дело воспитанности каждого.
     
  22. dAllonE

    dAllonE Guest

    Dagdamor, lexa давайте жить дружно.