Closed4
ソシャゲのフレンドシステムのDB構造を考えたい
趣味で作っているAPIにソシャゲのような フレンドシステムが必要になったので、それを実装するためのテーブル構造を考えたい回
※ 以下、普通のフロントエンドエンジニアが考える 趣味等小規模な環境での利用を想定したDB設計です。専門外なので、プロダクションでスケールする方法であるかどうかは全く保証できません。
要件
前提
- 既にusersというテーブルがあり、そこに
id
というプライマリキー とcode
というフレンド登録用ユーザー識別コードがある
フレンド申請の流れ
- ユーザーは、別のユーザーに フレンド申請を送ることができる
- ユーザーがフレンド申請を送ると、相手のユーザーのフレンド申請許可待ちリストに入る
- 同時に、申請したユーザーのフレンド申請中リストにも入る。
- ユーザーは、一度送ったフレンド申請をキャンセルすることができる
- ユーザーは、自分が受け取ったフレンド申請を 許可 または 拒否することができる
- ユーザーは、フレンド申請をほぼリアルタイムで確認できるものとする
フレンドの利用方法
- ユーザーは、クエストの開始前に まだフレンド登録していないゲスト・フレンド登録済みのフレンドからそれぞれ ゲスト30件 / フレンド40件 を取得した 利用フレンドキャラクター選択画面を経由する
- 都度全件取得は負荷がかかるため、"利用フレンドキャラクター選択画面"は1日1回リセットされる仕様
- ただしユーザーが再更新を選択すると、意図的に"利用フレンドキャラクター選択画面"を随時リセットできる
フレンド解除
- ユーザーは任意のタイミングで フレンドを解除することができる
- 片方がフレンド解除するともう片方もフレンドから消える
備考
- フレンド状態は 他人/一方登録/相互登録 の3ステータスがある
- "利用フレンドキャラクター選択画面"には ユーザーが自らのパーティに入れたキャラクターは出てこない
登場しそうなDBテーブル
-
ユーザー
-
フレンド申請状態テーブル
-
フレンドテーブル
-
フレンドキャラクター選択画面一時データ保持テーブル
ユーザー
type User struct {
Id value_friend.PlayerId `gorm:"primaryKey"`
Name string
Code string
}
フレンド (申請中)
type FriendRequest struct {
ManagedFriendId uint `gorm:"primaryKey"`
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
PlayerId1 value_friend.PlayerId `gorm:"index"`
Player1 model_user.User `gorm:"PRELOAD:false;foreignKey:PlayerId1"`
PlayerId2 value_friend.PlayerId `gorm:"index"`
Player2 model_user.User `gorm:"PRELOAD:false;foreignKey:PlayerId2"`
State value_friend.FriendState `gorm:"index"`
}
フレンド (成約済み)
type Friend struct {
ManagedFriendId uint `gorm:"primaryKey"`
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
PlayerId1 value_friend.PlayerId `gorm:"index"`
Player1 model_user.User `gorm:"PRELOAD:false;foreignKey:PlayerId1"`
PlayerId2 value_friend.PlayerId `gorm:"index"`
Player2 model_user.User `gorm:"PRELOAD:false;foreignKey:PlayerId2"`
}
フレンドキャラクター選択画面一時データ保持テーブル
恐らくこれは フレンド情報自体は丸ごとクライアントに返して、クライアント側でいい感じに絞り込みなりして表示しているのではないかと思う。なので、一度フレンドをランダムにピックアップして返し、その結果を一定期間保管しておくためのテーブルを定義する。
type FriendCache struct {
ManagedFriendId uint `gorm:"primaryKey"`
/** requester's player id */
PlayerId value_friend.PlayerId `gorm:"index"`
CreatedAt time.Time `gorm:"autoCreateTime"`
ExpiresAt time.Time
Direction value_friend.FriendDirection
/** another user's player id */
TargetPlayerId value_friend.PlayerId
TargetPlayer model_user.User `gorm:"PRELOAD:false;foreignKey:TargetPlayerId"`
}
このスクラップは5ヶ月前にクローズされました