Связующие записи/рекомендуемые товары. Как сделать?

Тема в разделе "Как сделать...", создана пользователем UDAV, 26 май 2014.

  1. UDAV

    UDAV

    Регистр.:
    22 июн 2007
    Сообщения:
    781
    Симпатии:
    153
    Задача сделать рекомендуемые товары. Движек сайта самописный на php.

    Подскажите лучшую реализацию. Я сейчас придумал только сделать доп.поле у товара и через запятую записывать id рекомендуемых товаров, потом через explode выводить их.

    Может есть более лучшее решение? Может хранить в отдельной таблице?
     
    Шумадан нравится это.
  2. ArtyGrand

    ArtyGrand Постоялец

    Регистр.:
    6 июн 2009
    Сообщения:
    81
    Симпатии:
    37
    Если не требуется в привязанных товарах выводить товар, к которому ты привязал, то вполне можно и так. Иначе можешь замутить табличку со связью многих ко многим.
    А id ты можешь и через автозаполение вводить, глянь как в опенкарте сделано.
     
    latteo и Шумадан нравится это.
  3. Шумадан

    Шумадан Хабарра!!11

    Регистр.:
    6 фев 2008
    Сообщения:
    1.722
    Симпатии:
    2.097
    самым лучшим будет реализация в виде отдельной таблички с внешними ключами, проблем с выборкой не дожно быть, да и целостность данных легко поддерживать, т.е. при удалении товара, ссылка на рекомендуемые позиции автоматически удаляется. А таблица может иметь очень простой вид
    id, product_id, recommended_id
    где id аутоинкремент и первичный ключ, а (product_id, recommended_id) уникальный, в таком случае можно задавать любое колличество сопутствующих товаров для текущего. + можно добавить дополнительное поле для определения вида, т.е. либо это рекомендуемый товар, либо товар который можно купить по скидке, но только вместе с этим. Типа related, upsell, crossell
     
    udav99, SilverGhost и latteo нравится это.
  4. DevOrc

    DevOrc Создатель

    Регистр.:
    5 июн 2014
    Сообщения:
    31
    Симпатии:
    10
    Если не использовать рекомендованные товары больше нигде, кроме как самого товара, то решение положить все в одно поле - идеально. Далее без всяких explode получить список рекомендованных в 1 запрос.

    Код:
    SELECT *
    FROM
      tbl
    WHERE
      id IN(recomend_set)
    где recomend_set и есть значение поля со списком рекомендованных идешников
     
  5. Шумадан

    Шумадан Хабарра!!11

    Регистр.:
    6 фев 2008
    Сообщения:
    1.722
    Симпатии:
    2.097
    ну как быстрое решение - да, но оно не гибкое :smmne:но тут скорее вопрос, как для определённого айди получить список рекомендаций, что в вашем случае не совсем работает
     
  6. DevOrc

    DevOrc Создатель

    Регистр.:
    5 июн 2014
    Сообщения:
    31
    Симпатии:
    10
    Гибкость тут не требуется, кто захочет выбрать весь список рекомендуемых вне контекста конкретного товара, надо отходить от правил нормализации, где этого не требуется. Гибкость это значит доп. расходы по производительности.
     
  7. Шумадан

    Шумадан Хабарра!!11

    Регистр.:
    6 фев 2008
    Сообщения:
    1.722
    Симпатии:
    2.097
    поясните мне как в вашем примере будет работать следующее
    есть товар с id = 2, у него рекомендируемые товары: 12, 22, 145, 17895
    есть товар с id = 3, у него рекомендируемые товары: 1, 2
    + есть 100000 товаров у которых нет рекомендируемых. вопросы
    1. как будут выглядеть записи в таблице товаров для обох случаем, где храняться ссылки на другие товары и как это выглядит
    2. какие запросы будут для того, чтоб получить рекомендируемы товары для 2 и 3
    3. какова будет разница в размере таблички, где 99098 записей будут пустыми? кстате, какой тип поля вы предлагаете для хранения сопутствующих товаров?
    ну и бонусом
    4. есть случай такой, товар с айди 666 используется в 99999 товарах, как рекомендированый, в разных товарах он рядом с другими рекомендируемыми, как быть, если товар нужно удалить? какой запрос нужно выполнить?
     
    vlad_ir нравится это.
  8. DevOrc

    DevOrc Создатель

    Регистр.:
    5 июн 2014
    Сообщения:
    31
    Симпатии:
    10
    1. Достаточно 1 доп. поля в таблицу с товарами varchar 400, выглядят как строки "12,22,145,17895" и "1,2"
    2. "И" не нужно вы сидите в одном товаре в один момент времени.
    3. Вы считаете что на индексы доп. таблицы физически уйдет меньше места?
    4. Ваши внешние ключи тоже подразумевают как минимум innodb. Ну и удалили
    Код:
    SELECT *
    FROM
      tbl
    WHERE
      id IN(recomend_set) and view=1
    этот запрос просто проигнорирует удаленный товар или спрятанный. Но если очень надо можно периодически проводить чистку.
    Например для удаленного товара с номером 2
    Код:
    update tbl set recomend_set = TRIM(BOTH ',' FROM REPLACE(CONCAT(',', recomend_set , ','), CONCAT(',', 2, ','), ','))
    5. Сразу пресеку возможный вопрос, varchar 400 вполне хватит.
     
    latteo нравится это.
  9. vlad_ir

    vlad_ir Постоялец

    Регистр.:
    13 июл 2007
    Сообщения:
    54
    Симпатии:
    18
    Шумадан прав. Вы не учитываете массу частных случаев, которые могут возникнуть в процессе эксплуатации Вашего скрипта. Взгляните на структуру баз данных популярных движков магазинов, и Вы поймете, что правильно хранить рекомендуемые товары именно в отдельной таблице, которая будет связана с таблицей товаров отношением многие к одному.
     
    Шумадан нравится это.
  10. DevOrc

    DevOrc Создатель

    Регистр.:
    5 июн 2014
    Сообщения:
    31
    Симпатии:
    10
    Все до единого движки магазинов тормозные и древние, покажите хоть один современный и быстрый. Почему надо брать за основу только распиаренный продукт? Никто не спорит что можно, порой и нужно, но в конкретном случае на выдаче товара быстрее работать будет так.