2

属性システムを備えた製品カタログがあります。

クライアントが属性別に製品を閲覧できるようにするシステムを作成したいと考えています (Magento のように)。そのため、特定の値を持つ属性 (または多くの特定の値を持つ多くの属性) を持つ製品のリストを (ID を返すことによって) プログラムで取得しようとしています。

それはうまくいきますが、私の SQL クエリはひどいものです!

例: これら 3 つの属性 (および値) を持つ製品のリストを取得する場合、現在の SQL クエリは次のとおりです。

  • 1 番目のフィルター: id_attribut = 3 AND 値 = 'Lorem ipsum'
  • 2 番目のフィルター: id_attribut = 4 AND 値 = 'Test2'
  • 3 番目のフィルター: id_attribut = 2 AND 値 = 'Bar2'

    SELECT products.id
    FROM製品
    JOIN products_attributes ON products_attributs.id_product = products.id
    WHERE products_attributs.value = 'ロレム イプサム'
    AND products_attributs.id_attribut = 3
    AND products_attributs.id_product ==> 戻り ID: 25、27
    の (
        id_product を選択
        FROM products_attributes
        WHERE id_attribut = 4
        AND 値 = 'Test2' ==> リターン ID: 27
        AND id_product IN (
            id_product を選択
            FROM products_attributes
            WHERE id_attribut = 2
            AND 値 = 'Bar2' ==> リターン ID: 27
        )
    )

結果: ID 27 を返します (これは、顧客が選択した 3 つの属性に対応する唯一の製品です)。

うまく機能しますが、エレガントではなく、あまり最適化されていません (10 個以上のフィルターがあると想像してみてください!)。

products_attributes テーブル:

--------------------------------------------------
| | ID | id_product | id_attribute | 値 |
--------------------------------------------------
| | 1 | 25 | 1 | フー | フー |
| | 2 | 25 | 2 | バー | バー |
| | 3 | 25 | 3 | ロレム・イプサム |
| | 4 | 25 | 4 | テスト | テスト
| | 5 | 27 | 1 | ふー2 |
| | 6 | 27 | 2 | バー2 |
| | 7 | 27 | 3 | ロレム・イプサム |
| | 8 | 27 | 4 | テスト2 |
| | 9 | 28 | 1 | ...など |
--------------------------------------------------

どうすれば改善できますか?

どうもありがとうございます!

4

1 に答える 1

1

「適切な」SQL を作成する唯一の方法は、すべての属性の列を作成することです。維持するのはかなり難しいので、お勧めしません。

それよりも、次のように、属性テーブルに複数回結合することができます。

SELECT p.id
FROM products p
LEFT OUTER JOIN products_attributs pa1 ON pa1.id_product = p.id and pa1.value = 'Lorem ipsum' AND pa1.id_attribut = 3
LEFT OUTER JOIN products_attributs pa2 ON pa2.id_product = p.id and pa2.value = 'Test2' AND pa1.id_attribut = 4
LEFT OUTER JOIN products_attributs pa3 ON pa3.id_product = p.id and pa3.value = 'Bar2' AND pa1.id_attribut = 2

幸運を。

于 2012-09-16T20:07:47.223 に答える