4

私は、ユーザーが(リアルマネーを使用して)クレジットを購入し、それらを物事に使うことができるWebアプリケーションを作成しています。

ユーザーがクレジットを購入または使用するたびに履歴を保持する必要があります。

ユーザーの現在のクレジット残高を知る必要があることがよくあります。

私は通常、同じデータを2回保存するのは悪い習慣です。つまり、クレジット残高の増減の履歴があるため、残高自体を別のフィールドとして保存するべきではありません。

ただし、ユーザーが新しいページ(現在の残高を表示する)を開くたびにこの残高を計算するのはやり過ぎのようです。一方、システムが毎回処理しなければならないのを防ぐために、データベースまたはWebサーバーのメモリに保存するのは間違っているようです。

誰かがこれを経験したり、この状況で推奨されるベストプラクティスを知っていますか?

4

4 に答える 4

4

私は同様の要件を持ついくつかのプロジェクトに取り組んできましたが、現在のバランスをその場で計算することに何の問題もありません。これはエラーが発生しにくいソリューションであり、この種のクエリはほとんどのデータベースが実行するように設計されています。Facebookレベルのトラフィックのあるサイトで作業しているのでない限り、のようなもの"select sum(transactionValue) from transactions where userID = ?"は非常に高速であるはずです。

残高を別の場所に保存する(実際には複製する)と、「キャッシュ」値が基になるトランザクションと同期しなくなり、微妙なバグや不一致が発生するリスクがあります。これを正しく行うために必要な作業量はおそらく重要です。

于 2013-03-21T09:25:52.697 に答える
2

非正規化にはその場所があります。たとえば、フォーラムトピックを含むテーブルには、すべてのトピックに対してPostCountを実行するのではなく、列もあります。COUNT(posts)一貫性が心配な場合は、定期的なチェックをスケジュールして(たとえば、特定のユーザーとの間の各トランザクションで)、各ユーザーBalanceがトランザクションの合計と一致するかどうかをテストできます。

于 2013-03-21T09:25:29.580 に答える
2

すべてのリクエストのクレジット残高を計算しないでください。
各ユーザーのクレジット残高は、維持する必要があります。

データベースに保管してください。
そうすれば、並行性について心配する必要はありません。
ユーザーがアプリケーションを使用するときに、トランザクションを使用してこの値をインクリメントします。
データベースは繰り返し選択するように最適化するので、繰り返しになりますが、データベースにそれを処理させます。

于 2013-03-21T09:26:31.720 に答える
0

残高の計算には時間がかかりますか?そうでない場合は、SQLを使用してリアルタイムで計算してください。

しかし、将来、トランザクションのログがどんどん大きくなる(数百万行)ときに問題が発生することを予測しています。トランザクションログからの選択クエリに時間がかかる場合は、残高をキャッシュして事前に計算し、データベースに保存します。

于 2013-03-21T09:27:24.730 に答える