Таблица Items:
id (PRIMARY KEY INTEGER)
Data (VARCHAR NOT NULL)
Type (INTEGER NOT NULL)
UserId (INTEGER NULL)
Ordered (TIMESTAMP NULL)
Организация работы с БД (sqlite)
Код:
Data - это сама уникальная строка, Type - это тип (для типов в отдельной таблице указаны цены), UserId - кто купил, Ordered - когда купил.
Последние 2 поля - необязательны, т.к. они заполняются лишь тогда, когда пользователь делает заказ. Ordered служит для последующей замены товара, а также идентификации заказа. По Ordered удаляются строки, у которых прошел "гарантийный" срок (с помощью cron или другого планировщика).
Функция order(): выполняется запрос UPDATE (с рандомной выборкой), который проставляет UserId и Ordered для текущего заказа. Затем выполняется SELECT ... WHERE UserId=(указанный id) AND Ordered=(время текущего заказа).
Проблема в том, что подсчет цен ведется только после выполнения процедуры заказа, что отнимает время (т.к. выполняем рандомный UPDATE).
Может я, конечно, чересчур загоняюсь (что нередкость), но как сделать так, чтобы подсчет цен на товар был "прозрачным" (т.е. не тратя время сначала на апдейт, потом селект)? Может стоит в корне поменять реализацию? Т.к. зашел в тупик - если один из пользователей покупает 1000 строк, делается UPDATE 1000 раз, потом подсчет цен, потом сверка с балансом пользователя. Считаю это нелогичным
P.S. Скрипт на Python 2.7
А по теме: может быть стоит делать insert? Я просто не очень понял суть работы этого всего. А цены считать исходя из того, какие типы покупаются? Хранить в памяти хэш тип=>цена и выдавать заранее. Но я всё равно не понял принципа работы, так что может так и нельзя делать.
Есть список, о котором я говорил выше (таблица Items):
Код:
id data type userid ordered
14 rapidshare.com/?id=o32jASjqe2 1 NULL NULL
16 sendspace.com/?id=3a4bc1231 2 NULL NULL
19 rapidshare.com/?id=312ASdasd 1 NULL NULL
14 rapidshare.com/?id=o32jASjqe2 1 NULL NULL
16 sendspace.com/?id=3a4bc1231 2 NULL NULL
19 rapidshare.com/?id=312ASdasd 1 NULL NULL
Есть отдельная таблица Prices:
Код:
id price
1 1.5
2 2.0
1 1.5
2 2.0
Сейчас логика работы такая:
Пользователь делает заказ. Выполняется запрос UPDATE, который заполняет поля userid ordered. После этого, выполняется подсчет суммы с помощью ф-ции total (на стороне SQLite). Заказ идентифицируется по userid и ordered. Если общая сумма заказа больше, чем баланс, то опять же выполняется запрос UPDATE, который очищает userid и ordered, указывая, тем самым, что товар свободен для покупки.
Проблема, собственно, в том, что мне кажется это не совсем логичным - "столбить" товар просто для подсчета суммы.
В реальной жизни ведь не обязательно доставать товары со склада, чтобы узнать общую сумму заказа.
С другой стороны, если использовать алгоритм из "реальной жизни", это замедлит процесс покупки, т.к.:
1. сначала нам необходимо сделать выборку (SELECT * FROM Items), посчитать общую сумму, и, после проверки баланса, "пометить" товар UPDATE'ом. Дело в том, что в это время кто-то может уже купить тот самый товар, который мы только что выбрали. Вероятность этого ведь есть?
2. замедление запроса UPDATE, т.к. этот запрос придется выполнять по выбранным id. Т.е. придется запускать его несколько раз. Выход есть, но он чуть более чем "извращенский" - это выделять ROWID во время SELECT и делать один запрос UPDATE. Будет выгдлядеть как UPDATE Items SET UserId=...,Ordered=... WHERE ROWID IN (row1,row2,row3,row4), где row1, row2 и т.д. - это номера строк, которые были получены при выборке.
Может у кого есть идеи?
1) UPDATE Items SET UserId=...,Ordered=... WHERE id IN (товар1, товар2 ... )
AND UserId IS NULL
2) SELECT ... FROM Items WHERE id IN (товар1, товар2 ... ) AND UserId <> наш_юзер -- показываем юзеру товары которые он не может купить т.к. они уже заняты