Оптимизировать SQL-запросы

Я столкнулся с интересной проблемой в очень простом случае. У меня есть таблица сообщений и пользователей в базе данных MySQL. Сообщения могут нравиться пользователям. Итак, есть отдельная таблица, называемая лайками, в которой есть столбцы: user_id, post_id.

Когда пользователь нажимает кнопку Like в приложении, выполняется запрос к скрипту php. Скрипт проверяет, есть ли в таблице строка, в которой post_id и user_id соответствуют информации из запроса. Пользователь не может поставить больше одного лайка к сообщению, и если я нажму лайк на уже понравившейся публикации, предыдущее лайк исчезнет

Сейчас использую 2 запроса: 1) проверьте, что лайк существует в таблице 2) Если записи нет - добавляю, а если есть - удаляю.

Теперь я вижу, что в моей таблице есть двойные лайки для одного и того же сообщения от одного и того же пользователя. Кажется, что два запроса от одного пользователя могут быть выполнены практически мгновенно.

Как его оптимизировать - чтобы нельзя было добавить два лайка к одному посту от пользователя? Я думаю, что вместо этого мне нужно выполнить один запрос, но что это должно быть?

вам нужно разместить образцы запросов, если вам нужен лучший ответ. Это поможет пользователям лучше понять вашу проблему.

LahiruTM 03.09.2018 07:22

Я думаю, вам нужно синхронизировать вызов со своим PHP-скриптом

codeLover 03.09.2018 07:27

посмотрите ТАБЛИЦЫ БЛОКИРОВКИ - чтобы избежать одновременных обновлений. ЗАБЛОКИРУЙТЕ таблицу перед SELECT и UPDATE - после завершения; РАЗБЛОКИРОВАТЬ ТАБЛИЦЫ

Madhur Bhaiya 03.09.2018 07:36
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
0
3
62
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

просто используйте флаг (столбец со значением 0 или 1) и обновите значение, не удаляя всю строку.

ваши шаги должны быть следующими:

  1. проверьте наличие строки.
  2. если существует, обновите столбец (например, - 1, в отличие от - 0)

Это оно.

в шаблонах проверьте на 0 или 1 для непохожего и похожего

Не нужно ничего «проверять».

Strawberry 03.09.2018 08:22

проверка предназначена для отображения значка типа / отличия в шаблоне внешнего интерфейса

kalanamw 04.09.2018 11:26
Ответ принят как подходящий

Очевидно, что ваша часть вставки / обновления запускается несколько раз. Вы должны выяснить, почему это происходит, а затем, если возможно, предотвратить это.

Из-за нескольких вызовов СУБД несколько раз запрашивает, существует ли запись. На все звонки ответ отрицательный. Затем запускаются несколько вставок, и вы получаете дубликаты. Итак, со стороны SQL есть две ошибки:

  1. Почему можно даже вставить несколько записей для одного и того же сообщения и пользователя? Чтобы это было невозможно, необходимо предоставить первичный или уникальный ключ.

Считаю это обязательным для вашей датамодели.

  1. Последовательность действий неправильная. Возможным решением может быть сначала вставка (один будет успешным, другие не удастся - вышеупомянутый ключ, конечно же, предоставляется!), А в случае неудачи будет выпущено обновление. Однако MySQL может сделать это даже за один шаг:

с ON DUPLICATE KEY:

insert into likes (post_id, user_id, like_date)
 values (@post_id, @user_id, current_date)
 on duplicate key update like_date = current_date;

Используйте InnoDB, затем

START TRANSACTION;
SELECT ... FOR UPDATE;
if it does not exist
    INSERT ...;
else
    DELETE ...
COMMIT;

Используя семантику транзакций, вы избегаете проблем, связанных с наступлением нескольких подключений друг на друга. Думаю, я даже избежал тупика.

Другие вопросы по теме