Виталий Я.
659 повідомлень
#13 років тому
Всем привет, сразу к вопросу:
Есть таблица с количеством очков, набраных посетителями, и есть скрипт, который должен менять одновременно по несколько значений набраных очков у РАЗНЫХ пользователей, и крайне желательно, чтобы за один запрос к базе.
Подскажите как сделать, у меня почему-то нет идей пока...
Виталий Я.
659 повідомлень
#13 років тому
Тоесть , наглядный пример:
Таблица : userid - score
Нужно выполнить что-то вроде:
UPDATE tablename SET score=score+100500 WHERE userid=1
UPDATE tablename SET score=score+200600 WHERE userid=2
UPDATE tablename SET score=score-9000 WHERE userid=3
Одним запросом. Как ?
Виталий Я.
659 повідомлень
#13 років тому
Нашел временное решение в виде
UPDATE tablename SET scrore=score+ CASE userid WHEN 1 THEN 100500 WHEN 2 THEN 200600 WHEN 3 THEN -9000 ELSE 0 END WHERE userid IN (1,2,3);
Если можете, подкиньте более подходящее решение. Или хотябы помогите оценить масштаб трагедии, в плане производительности таких запросов к БД.
Владимир Ф.
1322 повідомлення
#13 років тому
А зачем одним запросом?
Если надо атомарную операцию, то есть транзакции.
Евгений Ч.
6 повідомлень
#13 років тому
Если есть ключ по userid, то

INSERT INTO `tablename` (`userid`, `score`)
VALUES (1,100500),(2,200600),(3,-9000)
ON DUPLICATE KEY UPDATE
`score`=`score` + VALUES(`score`)

если записи с добавляемым id не существует, то она создается
если существует, то увеличивается ее score
Виталий Я.
659 повідомлень
#13 років тому
jett, инсерт не подходит по причине относительности значений.
Хотел бы узнать что вы думаете по поводу операторов CASE и IN. Насколько оправдано их использование, если за 1 раз будут изменятся не более 4 строк ?
Владимир Ф.
1322 повідомлення
#13 років тому
В данном случае руки бы оторвал, если мне так бы сделали.
Похоже на оптимизацию типа "чем меньше строк в скрипте тем лучше"
Не забывайте про то, что это придется поддерживать, и может быть не вам.
Виталий Я.
659 повідомлень
#13 років тому
vovan_f, я то это знаю, потому и говорю что решение временное, и хочу сделать лучше, чем сейчас.
Андрей Халецкий
3562 повідомлення
#13 років тому
Напишите что нужно сделать (какая задача стоит, а не как лучше микроскопом забить гвоздь).
Роман В.
99 повідомлень
#13 років тому
START TRANSACTION;
UPDATE tablename SET score=score+100500 WHERE userid=1;
UPDATE tablename SET score=score+200600 WHERE userid=2;
UPDATE tablename SET score=score-9000 WHERE userid=3;
COMMIT;


таблицы InnoDB гарантируют атомарность - или выполнятся все апдейты или ни одного.
Сергей К.
1649 повідомлень
#13 років тому
Цитата ("SmartDesign"):
как лучше микроскопом забить гвоздь


Xazzzi, не всегда 1 запрос лучше 4. Все зависит от поставленной задачи.