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

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

新規登録して質問してみよう
ただいま回答率
85.48%
データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

teratail

teratail(テラテイル)は、プログラミングに特化した日本語Q&Aサイトです。

Q&A

解決済

3回答

2752閲覧

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

退会済みユーザー

退会済みユーザー

総合スコア0

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

teratail

teratail(テラテイル)は、プログラミングに特化した日本語Q&Aサイトです。

3グッド

6クリップ

投稿2016/07/14 04:33

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

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

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

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

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

stereo_code, mty.ad, av-👍を押しています

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

以前、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 05:23

mty.ad

総合スコア145

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mty.ad

2016/07/14 05:37 編集

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

退会済みユーザー

2016/07/14 10:50

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

0

>mulberryfieldsさん

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

######理由1:更新のオーバーヘッドが高い
ランクという値の性質上、アクションを行ってランクが上がった人だけでなく、
アクションしていない人も、追い抜かされることで、ランクの更新が必要です。

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

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

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

投稿2016/07/14 05:10

ka_ei

総合スコア207

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/07/14 10:53

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

0

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

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

投稿2016/07/14 05:08

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/07/14 10:54

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問