@vikweb
web-программирование и it-консультации

Как одним запросом сделать проверка на наличие записи перед insert по четырем полям?

Всем привет.
Подскажите как можно сформировать запрос так, чтобы insert отправлялась одним запросом.
Есть таблица :
CREATE TABLE IF NOT EXISTS `wp_views` (
`post_id` bigint(20) unsigned NOT NULL,
`user_id` bigint(20) unsigned DEFAULT NULL,
`ip_address` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
`created_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
`session_id` varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
KEY `fk_posts_id` (`post_id`),
KEY `fk_users_id` (`user_id`),
KEY `k_ip` (`ip_address`(20))
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;

Нужно вставить новую запись так чтобы было учтено условие:
не было повтора post_id, не было повтора user_id , не было повтора ip_address и не было повтора session_id в течении одного дня. То есть если сегодня запись для post_id=1,user_id=1,ip_address='0.0.0.1',session_id='dsfsdfsdfsffsdfs' уже была добавлена то больше добавить сегодня было ничего нельзя. А завтра снова можно было бы добавить.
Решение запроса через php нельзя: поступает огромное количество запросов (больше 20 в секунду) и если разбивать на два то появляются дубликаты.
  • Вопрос задан
  • 218 просмотров
Решения вопроса 1
@vikweb Автор вопроса
web-программирование и it-консультации
Всем спасибо. Учел все предложения. Задача решена.
1. Преобразовал поля ip_address (varchar(15)) и session_id (varchar(50))
2. Добавил поле date_day (date)
3. Запустил UPDATE `wp_views` SET `date_day` = DATE(`created_date`)
4. Создал сложный уникальный ключ post_id-user_id-date_day-ip_address-session_id
И все заработало
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 3
@vyrkmod
Пишу на php. И не стыдно.
Вариант: добавить поле DATE куда будет писаться текущий день и собрать уникальный индекс из этого и четырёх полей из задачи. Условие будет выполняться железно. Только вот пользователям будут показываться какие-то ошибки базы данных, а за это можно и канделябром...
Решение правильное: в php перед записью проверять наличие сегодняшнего поста и нормально описывать пользователю почему у него что-то не получилось. И хайлоад тут не проблема.
Ответ написан
romy4
@romy4
Exception handler
Да, как сказал vyrkmod добавить поле Date и уникальный ключ на все 4 поля. Но нет никакой проблемы нормально обрабатывать ошибки mysql и увидев ошибку duplicate key делать что-то другое по логике.
Решение проверять допзапросом в php. ну такой себе вариант.
Ответ написан
Комментировать
ThunderCat
@ThunderCat Куратор тега MySQL
{PHP, MySql, HTML, JS, CSS} developer
делаешь ключ составным из полей post_id, user_id, ip_address, session_id, created_date, делаешь уникальным, и при вставке делаешь инсерт ор апдейт он дупликэйт. Немного черезпопно, но задачу вроде решает.

пока тоже рассматривается такой вариант , но придется таблицу "перешерстить" и в кодах учитывать это новое поле.
Если уже тормозит база/код, все - без рефакторинга в любом случае не обойтись, надо брать и делать.

Как вариант: поставить редис и хранить "внутридневной" ключ в нем, например хеш от этих значений, с экспайром до конца дня. При наличии ключа ничего не делать, сократится число запросов в бд, а редис отрабатывает практически моментально и уж точно гораздо быстрее дб.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы