私はこの現在の設定を持っています:
製品
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秒かかりました
データセットがこれほど大きくなると、クエリの最適化と多くのキャッシュ機能の使用のバランスを取ることが問題になると思います。正規化は、今日のハードウェアでも速度に関しては本当に邪魔になります。