質問: 現在、複数人でチャットができる機能の開発を行っています。 フレームワークには Ruby on Rails, データベースには MySQL を使用しています。 聞きたいこと ------ 今回はチャットの未読数を表示する機能の実装方法について質問があります。 未読数の仕様は、Messenger, LINE, Slack などに付いている機能と似たようなもので、 未読数はチャットのチャンネルを表示したときにリセットする仕様を考えています。 構成について ------ 今回実装するチャット機能には複数人でチャットを送受信できるチャンネル機能があり、 データベース設計は以下のようになっています。 **データベース構成** ``` users - id: integer - email: string - password: string messages - id: integer - channel_id: integer - sender_id: integer - content: text - created_at: datetime channels - id: integer - owner_id: integer - name: string - created_at: datetime subscriptions - id: integer - user_id: integer - channel_id: integer - read_at: datetime ``` ※ `sender_id` , `owner_id` には user の `id` が入ります ※ subscriptions テーブルにはチャンネルを購読しているユーザーを保存しています ※ `read_at` にはチャンネルページを表示した日時を保存しています 一部説明に不要と思われるカラムは省略しています。 考えたこと ----- 未読数の表示機能を開発するにあたり、以下の2つの方法を考えました。 **[方法1]** subscriptions テーブルに `unread_count` という未読数を保存する数値型のカラムを追加し、 メッセージの送信時に購読者全員の `unread_count` をインクリメントします。 ユーザーがチャンネルページを表示したときに `unread_count` をゼロにします。 **[方法2]** messages テーブルの `created_at` が subscriptions テーブルの `read_at` より大きいメッセージの数を チャンネルの表示時にカウントし、それを未読数として表示します。 ### それぞれの方法の比較 方法1の場合は、送信のたびにデータベースを更新するので、送信時のオーバーヘッドが大きいです。 また、方法2の場合は、チャンネルページを表示した日時を取得する `read_at` は機能として必須なため、 その更新のオーバーヘッドは無視するとして、表示のたびにカウントをしなければならないので、 表示時のオーバーヘッドが大きいです。 最後に --- 方法1、方法2どちらのほうが良いか、あるいは別の方法があればご教示いただけると幸いです。 よろしくお願いいたします。
回答: 自分だったら方法1より2を選択します、参照系の処理であればキャッシュやKVSを使用すれば表示時のオーバーヘッドは無視できるレベルだと思います。