Предложение альтернативного подхода:
Раньше я сталкивался с точно такой же проблемой на работе. Я потратил хорошую неделю, пытаясь найти лучший способ сделать это. Я закончил с созданием таблицы соединения, как вы сделали, но таблица содержит только непрочитанных сообщений вместо отслеживания read сообщений.
Поскольку
- Статус-кво: «все прочитали все свои сообщения».
- Получение непрочитанных сообщений (или их количества) должно быть максимально быстрым.
- Статус-кво должен быть наименее напряженным состоянием в системе.
Теперь, если бы я отслеживал все сообщения, которые все прочитали, беспорядок в базе данных растет довольно быстро ( пользователей * сообщений строк), что легко приводит к тысячи рядов «мертвого веса» даже в небольших приложениях. Эта проблема преувеличена, если время жизни сообщений неопределенно - вы можете отслеживать статусы сообщений, которым много лет.
Если отслеживать обратное, ваша таблица «непрочитанных сообщений» содержит только несколько строк, и они уменьшаются для каждого сообщения, которое читает пользователь. Кроме того, получить количество непрочитанных сообщений так же просто, как «SELECT COUNT(*) FROM unread WHERE user = foo
».
Но
Как и все, это компромисс. В то время как чтение является в значительной степени быстрым, насколько это возможно в вычислительном отношении, письмо является рутиной. Для каждого письменного сообщения вам необходимо вставить запись в эту таблицу соединений. Кроме того, если несколько человек могут прочитать одно и то же сообщение, вам нужно вставить одну строку для каждого получателя. Если получатели неявные (например, дается только имя группы пользователей или даже с такими критериями, как «любой, кто имеет доступ к этой вещи»), создание новых сообщений становится еще более сложным.
Но я чувствую, что это справедливый компромисс.
YMMV, HTH.