Я пытаюсь создать функцию "Мне нравится" для сообщений.В моем веб-приложении есть таблица для пользователей и одна для записей.Я создал новую таблицу с именем Like_posts
, в которой я сохраняю, кому из пользователей понравился какой пост.
Одно основное ограничение, которое каждому пользователю может понравиться пост только один раз.если пользователь нажимает кнопку «лайк» для записи, которая ему / ей уже понравилась, он переключает / удаляет статус «лайк».
Основная логика:
Если пользователь нажимает «лайк»и
, если like_posts
уже содержит строку с user_id
и post_id
, удалите строку (т. е. пользователь решил не любить ранее понравившийся пост), иначе добавьте новую строку с post_id
и user_id
.
В настоящее время я запускаю 2 отдельных запроса, сначала чтобы проверить, существует ли строка, а затем мое приложение решает, следует ли его вставить или удалить.Учитывая, что я ожидаю, что «like» - одна из наиболее часто используемых функций, которые изменяют данные БД, я действительно хочу сделать это одним запросом.
Я знаю, что могу сделать это с помощью массивов (liked_by
--> user_id
в таблице сообщений) но я не хочу идти по этому пути.Развертывание и воссоздание массивов с использованием различных данных не очень производительно, и я действительно не люблю использовать массивы или jsonb
в PG (не нравится API).
Я хочу использовать что-то вроде upsert, ноиз того, что я знаю, я могу делать только «О конфликте (один столбец)», пока мне нужно «О конфликте (как col1, так и col2)».
Какие у меня есть варианты и какой будет хорошим способомспроектировать переключение кнопки «Мне нравится» в моей базе данных?
Основываясь на прекрасном совете @Laurenz Albe, я смог улучшить подход.Теперь у меня есть уникальные ограничения на 2 столбца:
CREATE TABLE LIKE_POSTS (
POST_ID TEXT NOT NULL,
USER_ID TEXT NOT NULL,
CREATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UPDATED_AT TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
DELETED_AT TIMESTAMP,
CONSTRAINT "Unique_user_and_post_combo" PRIMARY KEY (POST_ID, USER_ID)
);
insert into like_posts (post_id, user_id) values (1,1);
Я до сих пор не уверен, как выполнить действие удаления.Что-то вроде;
insert into like_posts (post_id, user_id) values (1,1)
returning "ON"
ON CONFLICT ON CONSTRAINT Unique_user_and_post_combo
DO DELETE RETURNING "OFF";