Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помощь в составлении запросов 
V
    Опции темы
aktuba
Дата 26.8.2007, 09:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: нет
Всего: 38



Надеюсь админы и модеры простят за 2 вопроса в одном топике, т.к. оба вопроса относятся к одной теме...

Возникла такая проблема. Есть таблица (users), в которой находится поле last - дата и время последнего действия пользователя. Соответственно - это поле часто обновляется через UPDATE. Решил оптимизировать: создать дополнительную таблицу (tbl_last), в которую перенесу поле last:
Код

1.ID
2.UserID
3.Last


Теперь возникла проблема с двумя запросами:
1. Обновление данных. Делаю следующим образом:
Код

INSERT INTO tblusers_lastvisit(userid, last) VALUES(mysql_escape_string($userid), time()) ON DUPLICATE KEY UPDATE userid=mysql_escape_string($userid)


Если записи для данного пользователя нет - она добавляется. Но если есть - добавляется еще одна(!) Как пофиксить?

2. Вывод списка пользователей. Вообще не знаю с какой стороны подойти. Необходимо из таблицы users получить всех пользователей и для каждого из них получить из tbl_last время последнего действия пользователя в системе (если есть запись о текущем пользователе) или null (если записи о текущем пользователе нет). Все что пытался сделать - не помогло, теперь надеюсь на Вас...


--------------------
user posted image
PM MAIL WWW Skype   Вверх
check
Дата 26.8.2007, 10:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 610
Регистрация: 3.4.2006

Репутация: 3
Всего: 23



Цитата(aktuba @  26.8.2007,  09:28 Найти цитируемый пост)
ON DUPLICATE KEY
Не пользовался такой штукой,  но подозреваю,  что это сработает только если userid будет первичным ключом(ну или не первичным но уникальным).   
А тут ведь ID который и является первичным ключом автоинкрементируется,  поэтому ON DUPLICATE KEY не срабатывает.

Добавлено через 14 минут и 21 секунду
И потом,  а зачем вообще что-то обновлять, если есть отдельная таблица для хранения времени последнего действия?   Наибольшее время для данного UserID это и есть последнее действие этого пользователя.


PM MAIL   Вверх
check
Дата 26.8.2007, 11:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 610
Регистрация: 3.4.2006

Репутация: 3
Всего: 23



Цитата(aktuba @  26.8.2007,  09:28 Найти цитируемый пост)
Вывод списка пользователей. Вообще не знаю с какой стороны подойти. Необходимо из таблицы users получить всех пользователей и для каждого из них получить из tbl_last время последнего действия пользователя в системе (если есть запись о текущем пользователе) или null (если записи о текущем пользователе нет).

Код

select us.id, us.name, max(last.Last)
from users us left join tbl_last last
on us.id=last.UserID
group by last.Last

PM MAIL   Вверх
aktuba
Дата 26.8.2007, 13:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: нет
Всего: 38



Цитата

Не пользовался такой штукой,  но подозреваю,  что это сработает только если userid будет первичным ключом(ну или не первичным но уникальным).   
А тут ведь ID который и является первичным ключом автоинкрементируется,  поэтому ON DUPLICATE KEY не срабатывает.


Если userid уникальный или первичный - работает только вставка нового значения, т.е. если запись для текущего пользователя есть - вообще не происходит никаких действий! =(

Цитата

И потом,  а зачем вообще что-то обновлять, если есть отдельная таблица для хранения времени последнего действия?   Наибольшее время для данного UserID это и есть последнее действие этого пользователя.


Потому что - здравый смысл. Представь - пользователь посмотрел 20 страниц + написал на 10 страницах по 1 комментарию, плюс посмотрел и ответил в личке. Итого за один раз на пользователя будет более 30 записей в таблице. А если страниц не 20, а 50 + по 2 комментария на каждой странице - выйдет уже более 100 записей. Зачем столько мусора? Да и база будет заполняться быстро... Вот по этим соображениям и выбран даный подход.


--------------------
user posted image
PM MAIL WWW Skype   Вверх
muzer
Дата 26.8.2007, 14:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

Репутация: 30
Всего: 31



Цитата(aktuba @  26.8.2007,  14:47 Найти цитируемый пост)
Если userid уникальный или первичный - работает только вставка нового значения,

Вы просто не совсем уловили смысл конструкции ON DUPLICATE KEY UPDATE, надо написать так:
... ON DUPLICATE KEY UPDATE last = time();
т.е. что нужно сделать, если запись с таким первичным/уникальным ключом в таблице есть, сделать именно с этой записью в таблице.

Плюс, раз у вас есть отдельная таблица, то можно пользоваться вообще обычным REPLACE. Здесь ситуация такая: быстрее работать будет REPLACE, но постепенно будет портить индекс, т.е. фрагментировать его. А ON DUPLICATE KEY UPDATE индекс не портит, работает медленее. Если вы выбираете REPLACE, то нужно в какой-нибудь крон (ежедневный/еженедельный) поставить командочку OPTIMIZE TABLE table; для этой таблицы.

Плюс, вижу у вас в таблице бесполезное поле ID.
PM WWW   Вверх
aktuba
Дата 26.8.2007, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Смышленный
***


Профиль
Группа: Завсегдатай
Сообщений: 1915
Регистрация: 24.4.2006
Где: Планета Земля

Репутация: нет
Всего: 38



Цитата

Вы просто не совсем уловили смысл конструкции ON DUPLICATE KEY UPDATE, надо написать так:
... ON DUPLICATE KEY UPDATE last = time();


Не работает. Проверял и до этого, но сейчас убедился еще раз...

Цитата

Плюс, раз у вас есть отдельная таблица, то можно пользоваться вообще обычным REPLACE. Здесь ситуация такая: быстрее работать будет REPLACE, но постепенно будет портить индекс, т.е. фрагментировать его. А ON DUPLICATE KEY UPDATE индекс не портит, работает медленее. Если вы выбираете REPLACE, то нужно в какой-нибудь крон (ежедневный/еженедельный) поставить командочку OPTIMIZE TABLE table; для этой таблицы.


Не самый лучший вариант - REPLACE. Как я понимаю - эта команда удалит старую запись и создаст новую. Верно?

Цитата

Плюс, вижу у вас в таблице бесполезное поле ID. 


Да, привычка. smile Уже переделал - теперь таблица tbl_last содержит два поля: userid и last... Но как быть с UPDATE??? Не могу исправить...  smile

Добавлено через 3 минуты и 36 секунд
УРЯ!!!! Работает!

Ошибка была в названии поля... Сам виноват.

P.S.: muzer, check = +1


--------------------
user posted image
PM MAIL WWW Skype   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




[ Время генерации скрипта: 0.0477 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.