Как выбрать одну последнюю запись из таблицы-журнала

Royal Flash

-=MaestrO=-
В таблице хранится журнал пользовательских настроек. Каждый раз, при смене настройки пользователем, ему в журнал добавляется 1 запись. Этих записей может быть много - до 1000 шт. на 1-го пользователя. Не исключен вариант (для особо быстро меняющих данные пользователей), что разные записи журнала одного пользователя будут иметь одну и ту-же дату, поскольку точность колонки datetime - 1 сек. Можно ли за один запрос выбрать даты последних изменений для 20 пользователей, и если да, то каким запросом?

Таблица users_settings содержит: id (записи журнала), id_user, parameter, last_change_date.

Пробовал так:

SELECT max(id) AS id, id_user, parameter, last_change_date
FROM users_settings
WHERE id_user IN (..., ..., ...)
GROUP BY id_user

Вроде бы работает, но нет уверенности, что id_user, parameter, last_change_date соответствуют max(id)...

Возможно, стоит хранить дополнительно дату последнего изменения настроек в таблице пользователей (id пользователя, last_change_date, ...), чтобы не искать max(id) среди 1000 записей у каждого из 20 пользователей? Или же эти 1000 записей будут находится быстро, благодаря индексам?
 

zerkms

TDD infected
Команда форума
Этот запрос вернёт неизвестно что.

Если хочется быстро - то храни явное соответствие user_id -> last_setting_id
 

Royal Flash

-=MaestrO=-
А можно в студию запрс, который бы выводил то, что нужно? :) На счет хранения соответствий - согласен.
 

shelestov

я тут часто
SELECT max(last_change_date) AS last_change_date, id_user
FROM users_settings
WHERE id_user IN (..., ..., ...)
GROUP BY id_user

Но это если только даты нужны.
 

prolis

Новичок
Лучше хранить актуальные данные раздельно от журналов изменений (в другой таблице)
 

Royal Flash

-=MaestrO=-
shelestov спасибо, но это как масло маслянное :) Т.е. мне нужны не только даты.
prolis лучше, в плане быстродействия, согласен.
 

shelestov

я тут часто
Сам бы я это не решился использовать.
SELECT * FROM users_settings WHERE id in (SELECT max(id) WHERE id_user IN (..., ..., ...) GROUP BY id_user);
Я полностью согласен с prolis. Актуальные настройки и логи по их изменениям надо несомненно хранить в разных таблицах. Тогда такого изврата не потребуется.
 

Royal Flash

-=MaestrO=-
Ну а если этих настроек 20, 30, 50? Для каждой прийдется отдельно заводить в главной таблице ее последний id в истории, значение и последнюю дату изменеия. В итоге получится такая не мальнекая БД...
 

shelestov

я тут часто
Ну а если этих настроек 20, 30, 50? Для каждой прийдется отдельно заводить в главной таблице ее последний id в истории, значение и последнюю дату изменеия. В итоге получится такая не мальнекая БД...
Получится нормальная структура!
В таблице users_settings будут просто храниться текущие настройки, в таблице users_settings_changes будет храниться история их изменений.
Текущие настройки вы всегда сможете взять из основной таблицы, логи по их изменению из changes.

Граматная страктура намного важнее размера базы.
Но излишнего (не нужного) дублирования данных в таблицах быть не должно, т.к. это противоречит принципам реляционных баз данных.
В любом случае нужно смотреть в сторону производительности, где будет выйгрыш, там и истина.

Но возможно я не правильно понимаю вашу задачу.
 

prolis

Новичок
Я не могу себе представить цели хранения истории изменения пользовательских настроек
 

Royal Flash

-=MaestrO=-
Я не могу себе представить цели хранения истории изменения пользовательских настроек
prolis - Вам этого делать и не нужно, так как это пример. Зато, если подумать, можно представить другие задачи, в которых применяется такая структура БД :) Например, финансовые операции и др.

Получится нормальная структура!
shelestov - получается так, но немного, так сказать, раздутая... Но поскольку других вариантов я не нашел, буду использовать как есть :)

P.S. Кстати, нашел чисто случайно таки ответ на свой вопрос: http://itif.ru/mysql-vybor-poslednih-valut/
 
Сверху