9

RailsとMySQLを使用していますが、行のカウントに基づく効率の質問があります。

私はそのProjectモデルを持っていhas_many :donationsます。

プロジェクトのユニークなドナーの数を数えたいです。

projectsテーブルにと呼ばれるフィールドがありnum_donors、新しいドナーが作成されたときにそれをインクリメントするのは良い考えですか?

それとも@num_donors = Donor.count(:select => 'DISTINCT user_id')、データベースの最適化のおかげで、効率の点で類似または同じになるようなものですか?user_idこれには、カウントしたい他のフィールドのインデックスを作成する必要がありますか?

寄付総額の合計についても同じ答えが当てはまりますか?

4

5 に答える 5

17

タイトルの質問に答えます。はい、それは冗長ですが、あなたがそれをすべきかどうかはあなたの状況に依存します。

パフォーマンスの問題がわかっている場合を除いて、アプリケーションでその場でカウントと合計を計算し、保存しないでください。つまり、他に選択肢がない場合を除いて、計算値を保存しないでください。

ほとんどの場合、これに頼る必要はなく、そうすべきではありません。

計算値を保存する必要がある場合は、次のようにします。

  • インクリメントして最新の状態に保たないでください。更新するたびに、すべてのデータからカウント/合計を再計算します。
  • 更新があまりない場合は、コードを更新トリガーに入れて、カウント/合計を最新の状態に保ちます。
  • データベースの冗長性に関する問題は、数値が一致しない場合、どちらが信頼できるかわからないことです。ドキュメントに、ソースデータが一致せず、上書きできる場合は、ソースデータが信頼できるソースであることに注意してください。
于 2009-10-03T00:39:33.717 に答える
9

データベースのサイズにもよりますが、これらはデータベースが専門とする種類の操作であるため、高速である必要があります。これはおそらくここでの時期尚早の最適化のケースです-合計を保存しないことから始めて、それをより簡単にする必要があります-そして必要に応じて後で最適化します。

于 2009-10-03T00:32:22.690 に答える
7

「時計を1つ持っている人は常に時間を知っています。時計を2つ持っている人は決して確信が持てません」という格言を覚えておいてください。 次の場合にのみ、派生番号を保存します。

パフォーマンスの問題により、必要なときに派生番号を取得できなくなります(この場合、インデックスから回答が得られる可能性が高いため、問題にはなりません)。

また

プログラマーのエラー、意図的または偶発的なユーザーアクションによって、メインテーブルからレコードが失われていると考える理由があります。その場合、導出された数値を使用して、現在計算されている数値を監査できます。

于 2009-10-03T02:46:15.243 に答える
5

PeterとJohnFxの答えは正しいです。あなたが提案しているのは、データベーススキーマの非正規化です。これにより、読み取りパフォーマンスは向上しますが、書き込みが損なわれると同時に、開発者(または追加のDBMSクリーバー)に負担がかかり、内部の不整合が防止されます。データセット。

ActiveRecordには、has_many関係のカウントを自動的に管理する機能が組み込まれています。カウンターキャッシュでこのRailscastをチェックしてください。

于 2009-10-03T02:28:41.080 に答える
3

単純なフラグがActiveRecordの魔法をかけることを知っていますか?

class ThingOwner

# it has a column like
# t.integer things_count, :default => 0

has_many :things, :counter_cache => true

end

質問に関しては-ええ、それは冗長であることを確認してください。時間のシェアが大きすぎる場合にのみ、そのようなカウンターを追加します。things.count

そうでなければ、それは時期尚早の最適化です。

于 2009-10-03T07:24:22.890 に答える