Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Организация работы с БД (sqlite)

7.2K
09 сентября 2010 года
polaroid
94 / / 05.07.2008
Доброго времени суток. Делаю проект с использованием SQLite - что-то типа интернет магазина. Есть список, в котором каждая строка уникальна, и, собственно, является товаром. Задача - сделать распродажу строк этого списка, причем сделать так, чтобы пользователь имел возможность заменить неподходящую ему строку на другую (в течение "гарантийного" срока). Т.к. строки можно условно разделить на типы, а каждый тип имеет свою, установленную администратором, цену, то я сделал таблицу со следующими полями:
 
Код:
Таблица Items:

id (PRIMARY KEY INTEGER)
Data (VARCHAR NOT NULL)
Type (INTEGER NOT NULL)
UserId (INTEGER NULL)
Ordered (TIMESTAMP NULL)


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
366
09 сентября 2010 года
int
668 / / 30.03.2005
//В sqlite вроде нет varchar и timespamp.
А по теме: может быть стоит делать insert? Я просто не очень понял суть работы этого всего. А цены считать исходя из того, какие типы покупаются? Хранить в памяти хэш тип=>цена и выдавать заранее. Но я всё равно не понял принципа работы, так что может так и нельзя делать.
7.2K
15 сентября 2010 года
polaroid
94 / / 05.07.2008
Конкретно меня смущает логика моей теперешней реализации.
Есть список, о котором я говорил выше (таблица 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

Есть отдельная таблица Prices:
 
Код:
id  price
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.8K
16 сентября 2010 года
LM(AL/M)
332 / / 20.12.2005
пусть подсчёт суммы и проверка баланса происходит на стороне клиента, а потом на сервере сделаешь bulk update и все дела. чтобы разрулить ситуацию когда товар "захвачен" другим пользователем можно так поступить:
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 <> наш_юзер -- показываем юзеру товары которые он не может купить т.к. они уже заняты
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог