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

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

ただいまの
回答率

90.83%

  • Django

    813questions

    DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

  • データベース

    639questions

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

毎回計算するかデータベースに入れておくかの判断

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 117

mulberryfields

Google App Engine総合1位

Djangoで質問投稿サイトを作っています。
teratailのように、質問投稿や回答投稿やそれらに対する評価に応じて、スコアやランキングが出るようにしたいと思っています。

しかし、そのスコアやランキングを表示する際に、その都度毎回計算すべきか、スコアやランキングを保存するデータベースを作るべきかと悩んでいます。
例えば、teratailでも、ユーザー毎にスコアやランキングが付いていますが、このスコアやランキングは、これまでの質問や回答の投稿数やその評価などによって算定されていると思います。
しかし、このスコアは、ユーザーがページにアクセスする都度、そのユーザーの投稿した質問数や回答数やそれらの評価をデータベースから検索して、スコアを集計しているのでしょうか。だとすると、サーバーの負荷が非常に高くなってしまうと思います。
そのため、例えば、質問を投稿した時、回答を投稿した時、評価された時に、スコアが集計されていく感じにしているのかなと想像しました。とすると、下記のようなテーブルがあって、上記のアクションがあった時にこのスコアが集計されるのかと思ったのですが、どうでしょうか。
ユーザーが2人しかいなくて、タグが2つしかないという想定です。

ユーザーID タグID スコア
1 1 30
1 2 24
2 1 40
2 2 10

質問する度、回答する度に、当該ユーザーの当該タグのためのフィールドがテーブルに追加されていく感じかなと思っております。
一般的にどのようにこのような仕組みを作り上げるのかを知りたく、質問させて頂きました。
よろしくお願い致します。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+2

先ず、データベース設計における正規化で、第一正規化で導出項目(計算により求められる項目)は削除します。
当然計算により求められる項目について、計算に時間が掛かることは考えられますので、計算自体をどういったタイミングで行うのかも合わせたデータベース設計になってきます。

通常、時間の掛かる処理はデータ件数によるものが殆どで、時間を短縮するには、如何にその母数となる件数を減らすかに掛かっています。

例えば、必須条件を増やしたり、時系列的な範囲を狭めることを、仕様制限にしたり、
ある時点までの集計をとってそこからの範囲だけ集計を行うとか、要件を満たしつつ性能も担保するのには色々な方法があります。

最初から、アクセス数が大量と見込めるなら別ですけど、現段階では、計算によって求められる項目は作らず、そうなった時に検討で良いのではないでしょうか。

性能が問題になるような件数になった場合にはDISK資源の事も考えねばなりませんし、スケールアウトにも色々方法はあり、その構成に合わせた設計になりますので、検討はしても実装はせずというところでしょうか。

先ずは正規化して余分なものは削ぎ落してから、全体を見通した上で、拡張として考えるようにしてした方が上手くいくと思います。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/14 08:54

    ご回答、ありがとうございます。
    性能とDISK資源のトレードオフが生じるということですね。
    処理速度を上げるために、母数となる件数を如何に減らすかという点が重要ということもよく分かりました。

    キャンセル

+1

データの蓄積具合(の想定)によっても違うと思います。
少ないのでしたらDB取得のSELECT時にSUMしてもいいですし。
多いようでしたらtotal scoreテーブルか何かを作っておいて、
スコアの変動があるたびにUPDATEしておくというのもありと思います。
teratailのように個々の質問回答でどれくらいスコアしたかとか、
タグ毎のスコアも持つ必要があるのでしたらそれ毎にテーブルが必要ですね。

実際にどのように作られているかは作った人しか分からないので、
要件を整理してなるべく様々な形でのデータの持ち方を検証して
仕組みに合ったやり方を考えるしかないと思います。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/05/14 08:55

    ご回答、ありがとうございます。
    後々拡張していくことにしますので、取り急ぎ、DB取得時に計算する方法で実装しておき、遅くなってきたら、また検討したいと思います。

    キャンセル

  • 2018/05/14 10:43

    ある程度データの蓄積については先に想定しておいた方がいいかもしれません。
    後からDB分割したり変更するとなるとかなりのコストがかかり、既に動いているものへの大がかりな軌道修正となるので試験も大変です。

    キャンセル

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

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

関連した質問

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

  • Django

    813questions

    DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

  • データベース

    639questions

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