質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

87.49%

データベースを作った方が良いか、その都度計算させた方が良いかの判断

解決済

回答 3

投稿

  • 評価
  • クリップ 6
  • VIEW 2,219

score 811

webアプリを作成しています。
teratailでは、タグ別に順位表がありますが、私のアプリでも項目別に順位表を作成しようと考えています。
各項目毎に10位までの順位表を作成するにあたり、それ専用のデータベースを設けるべきか、その都度計算させた方が良いのかと考えています。

teratailでは、どういうデータベース構造になっているのかと勝手に想像してみました。
初心者なりに私が想像したのは下記の通りですが、どう思われますか?(テーブル名は勝手につけたものです)

【テーブル構成】
usersTagテーブル:フィールドは、ユーザー名、タグ名、スコアの2つ。
rankingテーブル:フィールドは、タグ名、順位、ユーザー名、スコアの4つ。予め、タグ毎に1位〜10位のレコードを登録できるようになっている。

【データ処理】
・ユーザーが、タグを登録すると、データベースのusersTagテーブルに、レコードが追加され、ユーザー名とタグ名が登録される。スコアはデフォルトの0。
・ユーザーが、質問を投稿したり、回答したり、ベストアンサーを付けてもらうと、
usersTagテーブルの当該ユーザーの当該タグの所に、一定のスコアを加算し、スコアを洗い替える。
そして、当該ユーザーのスコアと、rankingテーブルの当該タグの1位〜10位と比較し、rankingテーブルを洗い替える。
・順位表を表示する時は、rankingテーブルから直接引っ張って表示するだけ(その時に順位を計算するわけではない。)

順位表を表示する都度、順位を計算している訳ではないと思うのですが、どのように想像されますか?
同じような経験がある方、このような場合、どのようなテーブル構成とデータ処理をしたか、ご教示頂ければ幸いです。よろしくお願いします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

+1

以前、B2Cサービスの開発運営をしていた時は下記のような構成に致しました。

【データ構成】
スコアログ:MySQL -> ElasticSearch
ユーザー情報:MySQL
スコアランキング:Redis

【データ処理】 
1.スコアに影響がある処理の際にユーザー情報テーブルにスコアを更新
2.差分をログテーブルにinsert
3.スコアをredisに登録

※ログテーブルに書き込まれたスコアログはElasticsearchに集約

MySQLのI/Oをなるべく少なくするため(やはりユーザーとそれに付随するデータが貯まるほど顕著に遅くなるので)ランキング処理はすべてredisでまかなっていました。
Indexチューニングなどを行ってもやはり限界があります。

redisはsortedListを持つMemcacheのようなものと考えてもらえればわかりやすいと思います。
※メモリの監視をする必要があるが(なんでもそうか、)
設定によってはDisk書き込みで永続化も可能のよう(これはやってみてない)

テストとしてN万人xNタグ分のスコアなどのダミーデータを用意して比較してみればその差はすごい体感できます。

ちなにElasticsearchはログ収集と解析に使用していたので必要なければスルーして下さい。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/14 14:31 編集

    ※追記すると、ランキングというのはB2Cサービスにはほとんど持っているもので、それをどれだけ安く、早く、上手く実現する技術も多数存在していると思います。他にもこの様に実現しています。というような回答を見てみたいです。

    キャンセル

  • 2016/07/14 19:50

    ご回答いただき、ありがとうございます。
    ElasticSearchという単語で検索してみたら、
    teratailでも利用されているという記事が見当たりました。
    http://gihyo.jp/dev/serial/01/js-foundation/0008

    キャンセル

0

順位の算出にユーザーを待たせても良いとか、
算出のリクエスト数が許容範囲内なのであれば、
都度算出するのでもいいかもしれませんが、
待たせることになるためデータベースを作っちゃうのが無難なんじゃないでしょうか。

正確性もさほど重要でなければ、
データベース上に持たせて定期的に更新を加えるなど、
フォアグラウンド処理から外すとパフォーマンス確保できそうですし。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/14 19:54

    ご回答頂き、ありがとうございます。
    確かに、正確性を求めないのであれば、更新の頻度を落とすことでも負荷を下げれそうですね。

    キャンセル

0

>mulberryfieldsさん

作りを想像するのって、楽しいですよね。この業界を生業にしてるので私も癖になっちゃってます。
私は、ランク自体は値として持っていない(記載いただいたところのrankingテーブルはない)に、一票です!
理由としては、2点あります。

理由1:更新のオーバーヘッドが高い

ランクという値の性質上、アクションを行ってランクが上がった人だけでなく、
アクションしていない人も、追い抜かされることで、ランクの更新が必要です。

アクション×Nの更新が都度必要だと考えると、更新のオーバーヘッドが高いと考えられます。

理由2:検索はそこまで重くない

多いタグでも数千人程度しか登録していません。「Java」タグの登録者数を確認したら、
5632人でした。selectで約5000件を抽出して、順位付をするコストはそんなに高くないと考えられます。

※OracleでいうところのWindow関数のrankを使用することを想定
※usersTagテーブルがタグ別にパーティション化されていたら性能面は文句なし

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/07/14 19:53

    ご回答頂き、ありがとうございます。
    更新の負荷を減らすか、検索の負荷を減らすか、どちらを選択するかという判断になりそうですね。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 87.49%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る