0

私はこの現在の設定を持っています:

製品

product_id | product_name | category_id

カテゴリー

category_id | category_name

ベンダー

vendor_id | vendor_name | vendor_status

vendor_price

vendor_id | product_id | vendor_price

私が理解しているように、正規化の「ルール」によれば、次のような関係を宣言するテーブルがさらに2つあるはずです。

rel_product_vendor_price

product_id | vendor_price_id

rel_vendor_price_vendor

vendor_price_id | vendor_id

次に、vendor_priceという上記のテーブルでは、product_idが削除され、vendor_price_idが追加されます。

クエリが複雑になるため、物事をまとめるためにさらに2つのテーブルを作成する意味がわかりません。特にINSERTSは複雑であり、トランザクションで実行する必要があります。

現在、テーブルには300.000を超える製品が含まれており、それぞれに異なる価格の複数の異なるベンダーがあり、Sphinxでは150万を超えるドキュメントとしてカウントされます。

私は自分のデザインが間違っていますか、それともより正規化されたデザインに変更することに利点がありますか?

アップデート

すべての製品カテゴリを保持するためのテーブルがさらにあります。上記のスキーマを更新しましたが、最初の投稿でそれを忘れました。

通常、クエリをカテゴリに基づいて分割し、各カテゴリに属する​​すべての製品についてクエリを実行します。ユーザーが製品をクリックすると、その特定の製品のすべての価格を照会し、価格を降順で表示します。

ベンダーは一時停止される可能性があるため(vendor.vendor_status)、すべてのクエリは、ベンダーテーブルに戻るいくつかの結合を使用して実行する必要があります。

挿入物では、特定のベンダーの製品のすべてを削除します。外部キーの制約により、同じベンダーのすべてのベンダーの価格も削除されます。次に、productとvendor_priceに新しいものを挿入します。

これが理にかなっていることを願っています。

更新2

今夜多くのクエリテストを実行した結果、vendor_statusをvendorテーブルに保持すると、処理速度が大幅に低下することがわかりました。

データベースは、価格を選択するたびに、vendor_priceとvendorの間で選択を結合する必要があるため、たとえば、次の値を取得する際に非常に重要です。

MIN(vendor_price)AS min_vendor_price、MAX(vendor_price)AS max_vendor_price)

各vendor_price行にvendor_statusの複製を保持することは、多くの冗長データを意味しますが、それは実際に選択で物事をスピードアップします。

から

クエリに7.8040秒かかりました

クエリには3.1640秒かかりました

データセットがこれほど大きくなると、クエリの最適化と多くのキャッシュ機能の使用のバランスを取ることが問題になると思います。正規化は、今日のハードウェアでも速度に関しては本当に邪魔になります。

4

1 に答える 1

1

正規化は冗長なデータを排除しようとするため、挿入/更新/削除を一度に複数のテーブルで行う必要はありません。逆に、冗長データは多くの結合の必要性を排除することでクエリを高速化できますが、複数の場所での挿入/更新/削除に対処する必要があります. ベンダーIDと製品IDに基づいて価格を検索したいだけだと仮定すると、3つのテーブルスキーマは私には問題ないように見えますが、実行したいクエリの種類/保存する予定の他の種類のデータについての背景を教えてください.

于 2012-07-18T22:20:20.707 に答える