2016-11-18 7 views
0

モデリングソリューションの選択には助けが必要です。1対多の関係クエリでカウントするためのベストモデリング

私はテーブルBの多くの他のものに関連するレコードを持つテーブルAを持っています:例えば、テキスト(A)とそれを好んだユーザー(B)または製品(A)xレビュー(B)

だから、どれくらいの人がテキストをお気に入りにしたり、商品をレビューしたかを知りたい。これは、この状況のた​​めの唯一のクエリですが、テーブルが増えるにつれて複雑になることがあります。たとえば、クチコミ+商品に含まれているクチコミ+写真のレビューやレビューが全くないユーザー名を見つけたり、レビューに関連しているが調整のためにブロックされたりしているユーザー名を検索するなどです。表Aは、ちょうどテーブルBに関連しているレコード数をカウントするための列を持っている場合

はまだ、それは私が知っている、そのためにクエリを実行することは可能ですが、...

はそれがより良いソリューションですか? Favorite_Count、review_count、review_avgのように...

これは、誰かが好きな、または好きなものを選んでいないときに、ちょっとしたコーディングと引き換えに、複雑なクエリで「結合を保存する」でしょう。結局のところ、クエリは読みやすく、おそらく速いでしょう。

あなたはどう思いますか?

+1

このようにして集計データをテーブルに格納することは避けています。あなたのアプリケーションが誰かが言うべきことを誤っている場合は、これらの数字が一致していない場合、一致するかどうかを確認するプロセスが必要になります。次に、悪いアプリケーション書き込みを修正するためにアグリゲータを実行する頻度を管理します。他のアプリケーションがオンラインで購入されている間に、集計に問題が発生する可能性があります。 GROUP BYとINNER JOINSはお友達です。おそらく、読取り専用のデータベースを調べると、そこでレポートが実行され、そこでデータが平坦化される可能性があります。 –

+0

私はKamilのポイントを見ています。非常に重い読書状況では、あなたのBaseテーブルに更新された情報を管理することの複雑さを理解することができました。しかし、私はRossと通常は別の障害ポイント。さらに、詳細なデータと、パーティション化されたウィンドウ関数などの集約されたテクニックと適切なインデックスを持つCROSS APPLYが必要な場合は、最適化を行うことで、読み取り速度を速く保つことができます。 – Matt

+0

しかし、システムはAPIなどの外部からの入力を受けないので、実際には更新エラーは起こりそうにありません。とにかくそれは良い点です。 しかし実際の例を見てください。これは私がやろうとしていることであり、難しいです:http://stackoverflow.com/questions/40346096/designing-and-querying-product-review-system 私はブロックされていないレビューや製品を検討する必要があります数えられるだけでなく、レビューを平均化する(ブロックされずに隠されていないもののみ)。 私はSQLの専門家ではないので、それは私にとっては難しいことです。 : – mEba

答えて

0

データ検索が高速になります。データの挿入と更新が遅くなります。それはトレードオフです。比率は読み込みと書き込みに依存します。

StackOverflowがどのようにこれを行うかを調べることは、貴重なことです。データベーススキーマhereを調べることができます。

は、例えば、それらは容易Posts(階層構造)とPostTagsに参加それぞれ追加してたびに取得することができるにもかかわらず、Postsテーブル内AnswerCountTagsを置きます。

私の意見では、この情報は更新された情報よりも頻繁に読み込まれるからです。投稿リストを通過するユーザーの数と、実際に投稿ごとに何人がクリックしたかを想像してください。メインページに投稿リストを作成するには、誰かがそれを更新するたびにこれらの結合を実行するための時間が必要です。それは注目すべきトラフィックでしょうか?

しかし、それはすべてあなたのケースのシナリオによって異なります。この場合、「最良のアプローチ」はありません。

+0

はい、同じ場合があります。レビューを削除する/解除する/削除することができます。しかし、すべての単一の製品のために、そして大量の、プロダクトのリストにもなります。 – mEba

0

私はこの問題のインデックス付きのビューで良い経験をしました。これらはカウント計算に非常に適しています。 「通常の」ビューとは対照的に、レコードはSql-Serverのインデックスとして格納され、関連するテーブルが変更されると自動的に更新されます。しかし、これらにはいくつかの制限があります。スキーマバインディングは必須ですが、内部結合のみを使用できます。私は複数のインデックス付きビューを作成してからクエリを実行します。詳細については、MSDN Create Indexed Viewsを参照してください。

CREATE VIEW dbo.v_productReviewsCount 
    WITH SCHEMABINDING 
AS 
    SELECT T1.productId, 
     COUNT_BIG(*) AS [count] 
    FROM [dbo].[products] T1 
     INNER JOIN [dbo].[reviews] T2 
       ON T1.productId = T2.productId 
    GROUP BY T1.productId 

GO 

CREATE UNIQUE CLUSTERED INDEX ix_productReviewsCount_productId ON dbo.v_productReviewsCount (productId) 

GO