#sql #database #postgresql #schema #chat
#sql #База данных #postgresql #схема #Чат
Вопрос:
Я борюсь со схемой чата, которая разрешает удаление с одной стороны беседы в реляционной базе данных (PostgreSQL).
Вот мой лучший подход: моя схема
Все схемы, которые я нашел, касались удаления для обеих сторон, и это не то, что мне нужно. Я хочу иметь возможность удалять с одной стороны беседы, и если беседа возобновится, у пользователя 1 останутся все сообщения, а у пользователя 2 — только те, которые были отправлены после удаления. Итак, моя идея состоит в том, чтобы иметь много-много реляционных таблиц (deleted_messages), которые связывают сообщения с пользователями, и полностью заполнять эту таблицу, когда пользователь удаляет разговор с теми сообщениями, которые были в этом разговоре.
Однако я не уверен, что этот подход является лучшим, потому что моя база данных должна будет проверять, не было ли сообщение удалено для каждого полученного сообщения. Это будет все более и более запутанным по мере роста таблицы deleted_messages, и я беспокоился о производительности.
Есть какое-нибудь лучшее решение моей проблемы, или этот подход хорош? Спасибо за ваше внимание.
Ответ №1:
Как вы упомянули, «если беседа возобновится, у пользователя 1 останутся все сообщения, а у пользователя 2 — только те, которые были отправлены после удаления». Это приводит к 2 сценариям:
-
Если пользователь удаляет определенное сообщение, вам следует использовать схему того, что у вас уже есть.
-
Если пользователь удаляет историю чата, которая является точкой отсчета времени, вам следует создать отдельную таблицу, как написано ниже. Наличие одной записи для каждого сообщения в удаленном сообщении для одного пользователя вызовет серьезные проблемы с производительностью по мере увеличения объема данных. Создайте таблицу ниже и отфильтруйте данные на основе метки времени при извлечении данных.
создайте таблицу deleted_chat_history (userId int, chatroomID int, [timestamp] временная метка, внешний ключ (userId) ссылается на пользователя, внешний ключ (chatroomID) ссылается на chat_room)
Комментарии:
1. Я бы вообще не создавал другую таблицу, вместо этого добавил столбец, указывающий, что сообщение удалено (называется логическим удалением), а затем создал представление, которое устраняет эти сообщения. Фактическое удаление сообщений будет выполняться во время стандартной обработки архивирования сообщений. Преимущество заключается в меньшем обслуживании, поскольку у вас есть только 1 таблица, и при необходимости ее можно легко изменить,
2. @Blayer Вы не можете использовать только такой флаг, как is_deleted в этом условии, потому что это сообщение не удаляется для всех. Помните, что в chartroom может быть несколько пользователей, скажем, например, 10 пользователей, из которых 3 удалили историю сообщений в разные моменты времени, это не сработает с тем, что вы предлагаете.
3. @Blayer Кроме того, обновление, скажем, 100000 строк, допустим, разговора в истории чата с помощью is_deleted flat до 1 / true, было бы более сложной задачей, чем просто вставка 1 строки и выбор с помощью объединения. Таким образом, также упрощается обратимый процесс, поскольку вам не нужно переключать флаг для 1000 сообщений, вы можете просто удалить строку из новой таблицы.
4. В этом случае у вас есть m: m, поэтому вы помечаете таблицу разрешений.
5. @Belayer что вы подразумеваете под таблицей разрешений? Можете ли вы назвать ее по ссылке схемы, упомянутой выше.