こんにちは。
Webアプリケーションを作っていて、DB設計の部分に苦戦しています。アドバイスをいただければと思います。
概要
Ruby on Rails5を使って、TwitterのようなSNSを作ってみようとしています。
以下のようなモデルがあります。
*User:ユーザー
*UserFollowRelation:ユーザー同士にフォロー・フォロワーの関係を持たせる中間テーブル(from_user_id, to_user_idを外部キーとして持つ)
*Article:ユーザーの投稿(user_idを外部キーとして持つ)
このようなシステムで、タイムライン画面を作成してフォローしているユーザーの投稿のみ見られるようにしたいと考えています。
その実装の中で、素人目に見てもSQLにINを使った問い合わせが発生してしまい、レコード数が多くなると負荷が大きくなってしまうのではと疑問を持っています。
現状のソースは次のようになっています。
ruby
1# user.rb 2class User < ApplicationRecord 3 # フォローしているユーザー 4 has_many :following_user_relations, class_name: 'UserFollowRelation', foreign_key: 'from_user_id', dependent: :destroy 5 has_many :following_users, through: :following_user_relations, class_name: 'User', source: :to_user 6 7 # フォローされているユーザー 8 has_many :followed_user_relations, class_name: 'UserFollowRelation', foreign_key: 'to_user_id', dependent: :destroy 9 has_many :followed_users, through: :followed_user_relations, class_name: 'User', source: :from_user 10end
ruby
1class UserFollowRelation < ApplicationRecord 2 # user_follow_relation.rb 3 belongs_to :to_user, class_name: 'User' 4 belongs_to :from_user, class_name: 'User' 5end
ruby
1# timeline_controller.rb 2class TimelineController < ApplicationController 3 # deviseでログイン必須に(current_userを使えるように) 4 before_action :authenticate_user! 5 6 def index 7 # ここがINを使ったクエリになり、フォロー数が増えると負荷が大きくなる? 8 # current_userはユーザーID 1 9 # SELECT users.id FROM users INNER JOIN user_follow_relations ON users.id = user_follow_relations.to_user_id WHERE user_follow_relations.from_user_id = 1 10 # SELECT * FROM articles WHERE user_id IN (1,2,3,4,5,6,7,8,9) 11 @articles = Article.where(user_id: current_user.following_user_ids) 12 end 13end
質問内容
- 上記のTimelineController内でINを使っていて、フォローしている人数分だけINの中身が増えていくが、このような実装で数千人から数万人をフォローするようなシステムに耐えられるのでしょうか。
- そもそも、このようなことをしたい場合、根本的にテーブル設計が間違っているのでしょうか。
環境
- Ruby on Rails 5
- MySQL 5.7.20
質問するに当たって、情報が不足しているかもしれません。
すみませんが、お力を貸していただければと思います。
宜しくお願いします。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/01/28 04:25