За последние 24 часа нас посетили 17680 программистов и 1598 роботов. Сейчас ищут 1423 программиста ...

Корзина. Нужен алгоритм

Тема в разделе "Решения, алгоритмы", создана пользователем Koc, 1 апр 2009.

  1. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    В общем у меня сложности с составлением корзины для магазина.

    Нужно сделать так, что бы товары добавлялись в корзину вне зависимости от того авторизирован пользователь или нет (запись в БД по session_id?). Ессно записи по session_id будут иногда умирать сами по себе (прошло время сессии). Но это не проблема.

    Проблема в следующем: товары, добавленные в корзину авторизированным пользователем не должны умирать + при залогинивании должны мржиться с товарами, которые уже добавлены по SID и UID. Записи не должны дублироваться.

    то есть, сейчас имеет таблицу с уникальным индексом на первых 3 полях:
    users_cart(user_id, session_id, goods_id, quantity)
    если юзер не залогинен user_id=0

    предположим, что пользователь залогинился, добавились записи
    users_cart(3, 'str', 112, 2)
    users_cart(3, 'str', 101, 6)
    пользователь вышел
    добавил в корзину еще записи:
    users_cart(0, 'str', 101, 2)
    users_cart(0, 'str', 116, 9)
    зашел опять и мы должны привести его корзину к виду:
    users_cart(3, 'str', 112, 2)
    users_cart(3, 'str', 101, 8 )
    users_cart(3, 'str', 116, 9)

    на этом этапе все и рушится. Нужно сделать UPDATE что-то ON DUPLICATE KEY UPDATE.

    Возможно есть какие-то другие варианты как это реализовать?
     
  2. Frozen

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

    С нами с:
    20 окт 2008
    Сообщения:
    540
    Симпатии:
    0
    Адрес:
    Москва
    у нас когда человек заходит на сайт в первый раз, сразу же получает уникальный id. Тоесть в бд, независимо от того вышел или зашел человек, хранится его id, а не 0, null или чето там еще...
     
  3. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    этот id через сессии, куки хранится?
    что будет если он под своим логином добавит 10 товаров, потом перейдет на другую машину под другим айпи и зайдет в свой профиль? те 10 товаров будут там присутствовать?


    короче как я понял пока от моей идеи стоит отказаться.
     
  4. Andrey_Sergeev

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

    С нами с:
    17 дек 2008
    Сообщения:
    8
    Симпатии:
    0
    Можно вовсе не делать привязку к базе. Данные о заказе всегда хранить в cookie
    к примеру:

    количество товаров
    общая сумма
    товары (сериализованная строка)

    А пользователя подключать по мере надобности. То есть, при логине добавлять в cookie его id.

    При таком подходе совершенно не важно в какой момент времени пользователь совершил заказ. До регистрации в системе или после.
     
  5. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    привязка пользователю нужна для того, чтобы:
    человек че-то добавил к себе в корзину
    залогинился
    ушел куда-то
    вернулся под своим логином с другой машины
    товары по прежнему в корзине.

    Хотя наверно это глупость. но можно ж это вывести как опцию.
     
  6. klerick

    klerick Guest

    А почему бы сперва не делать все на куках, чтобы не было разницы откуда он покупает, а ему после каждой покупки напоминать, что для сохранения результатов необходимо в своем личном кабинете нажать на кнопочку "Зафиксировать" или "Сохранить". При нажатии происходит запись в бд.
    В случае, если он сохранил, а потом еще набрал всего, то, проверяя имеется ли у него покупка уже, выводить функцию "Добавить к имеющейся покупке".

    Не совсем удобный метод для пользователя, но так полностью можно контролировать его действия и не засорять БД попусту, когда зашел клиент, понажимал на "купить", а потом ушел с концами, а в БД записи остались.
     
  7. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    предлагаю считать, что бд безразмерная. Можно по крону поставить скрипт, который раз в сутки будет чистить неподтвержденные товары из корзины, которым больше N дней.

    на чистых куках хранить что-то не хочу. И в сессиях не хочу. Только в базе.

    зы: вроде не совсем меня поняли. Есть корзина, есть заказы. Заказов может быть много, они все зафиксированы, редактированию не подлежат (может только отмене и только те, которых еще одмин не видел). А корзина - она одна. Она для неоформленных заказов.

    Заказы доступны только юзеру, корзина - всем. Что бы оформить заказ (то, что сейчас в корзине), нужно залогиниться.
     
  8. klerick

    klerick Guest

    Я так понимаю, что и таблицы в БД тоже 2: корзина и заказы. Правильно?

    Тогда так: при входе на сайт SID записывать в БД (в таблице дополнительно 2 поля: sid и user_id). В том случае, если авторизации не произошло, то добавление в корзину проводить по sid. Во время авторизации пользователя во всех строках с sid в user_id прописывать его id и дальше работать по id. В том случае, если он сделает выход, то sid ведь остается, а снова вход, то...
    При переходе на другой компьютер при запуске и авторизации проверять, есть ли у него что-либо в корзине. Если да, то sid обновлять на текущий.

    Проблема в том, что зайдя из под другого компа, имея в корзине что-либо, до авторизации ты его никак не вычислишь... А после прийдется все перелапачивать и обновлять его корзину.
     
  9. Koc

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

    С нами с:
    3 мар 2008
    Сообщения:
    2.253
    Симпатии:
    0
    Адрес:
    \Ukraine\Dnepropetrovsk
    почти верно. Таблицы 3
    [sql]
    CREATE TABLE IF NOT EXISTS `tt_orders` (
    `id` int(5) NOT NULL auto_increment,
    `uid` int(5) NOT NULL, -- user_id
    `mid` int(5) NOT NULL, -- manager_id
    `timestamp` int(14) NOT NULL,
    `status` int(2) NOT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;

    CREATE TABLE IF NOT EXISTS `tt_orders_goods` (
    `oid` int(5) NOT NULL, -- order_id
    `gid` int(5) NOT NULL, -- goods_id
    `quantity` int(5) NOT NULL,
    `price` float NOT NULL
    ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;


    CREATE TABLE IF NOT EXISTS `tt_user_cart` (
    `sid` varchar(50) NOT NULL, -- session_id
    `gid` int(10) NOT NULL, -- goods_id
    `quantity` int(5) NOT NULL,
    UNIQUE KEY `uid` (`sid`,`gid`)
    ) ENGINE=MyISAM DEFAULT CHARSET=cp1251;
    [/sql]

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

    Еще нужно реализовать мерж. Это когда у пользователя по uid есть какой-то товар, не юзер добавляет себе этот товар по sid в корзину, залогнивается. И этот товар, который по sid и uid должен суммироваться.

    да, проблема, но имхо это нормальное явление.
     
  10. klerick

    klerick Guest

    В принципе не вижу большой проблемы. Если сделать так: в одной таблице(корзине) совмещаешь uid и sid, как уже писал. При добавлении товара не проверяешь,, есть ли он или нет, а всегда добавляешь его INSERT. Когда пользователь окончательно делает заявку на покупку, то все переписываешь в другую таблицу заявок посредством [sql]SUM(`count`) WHERE `gid`='blabla'[/sql], затем удаляешь записи из корзины. Т.е. проверка количества происходит не суммированием данных в одну строку, а потом с помощью стандартной SQL-функции SUM.