2

MySQL には製品テーブルがあり、各行にはコンマで区切られたオプションの値を持つフィールドがあり、組み合わせてこの製品になります。以下のスキームでは、両方のテーブルを見ることができます。カンマ区切りの値を持つフィールドは option_ids です。これは、たとえば 2,5,6,23 または 4,2,76 のようになります。これらの番号は、オプション テーブルに存在するオプションです。

製品:
|product_id|name|description|option_ids|price|

オプション:
|option_id|type_id|label|group|pos|count|price|

取得する入力は、一意のオプションの配列です。このオプションのセットまたはそのサブセットを持つすべての製品を option_ids で見つけたいと考えています。

これを行う方法は、オプションの配列のすべての可能な組み合わせを得るために、オプションの配列のべき集合を生成することです。次に、「OR WHERE」ステートメントでこれらすべての組み合わせを照会する mysql クエリを生成します。

ここでの問題は、累乗が指数関数的に増加することです。そのため、16 個の一意のオプションの配列がある場合、累乗は 65536 の可能性の配列を提供します。これを適切に機能させるには、php のメモリ使用量を増やす必要がありましたが、クエリが非常に膨大になるため、MySQL の問題が発生しました。

この問題に取り組む別の方法はありますか?

十分な情報を提供したことを願っています。そうでない場合は、質問してください。

編集: サブセットを見つける必要があるため、3 番目のテーブルでも同じ問題が発生します... オプションの配列が 1 つの製品であるとは言いません。1 つの製品である場合もありますが、2 つまたは 3 つの製品である場合もあります。例: オプション 1,2 は製品 A を作成し、オプション 2,3 は製品 B を作成し、オプション 4,5,6 は製品 C を作成します。オプション配列 [1,2,4,5,6] がある場合、製品 A と C を見つけます。

4

3 に答える 3

4

3番目のテーブルを使用します。

Product_Option_Assoc(product_id、option_id)

製品に必要なすべてのオプションについて、そのテーブルに行を挿入します。これにより、製品とオプションの間に実際の1対多の関係が得られます。オプションの数は簡単に変更でき、データのプルと更新のクエリも簡単です(コンマ解析は必要ありません)。

クエリの例:オプションが関連付けられている商品を取得します。

$options = array(1, 55, 23); // hard coded but could come from a form (remember to validate/cast as ints)
$optionCommaList = implode(',', $options);

SELECT
    p.name
FROM
    Product_Option_Assoc a
LEFT JOIN
    Products p ON p.product_id = a.product_id
WHERE
    a.option_id IN ($optionCommaList);
于 2012-12-14T11:45:27.713 に答える
0

FIND_IN_SET(str、strlist)を使用するとうまくいきますか?

効率についてはわかりませんが、特定のオプションを備えた製品を簡単に検索する方法を提供します。

于 2012-12-14T11:46:58.617 に答える
0

オプション リストを 1 つの文字列に変えると、データベースのすべての機能が失われ、文字列の一致やその他の面倒な作業を行わざるを得なくなります。リンクテーブルを使用します。それは正しい方法です。次に、それに対するクエリの書き方を理解します。

Product_option ( product_id, option_id )

これはあなたが望むものです:

例: オプション 1,2 は製品 A を作成し、オプション 2,3 は製品 B を作成し、オプション 4,5,6 は製品 C を作成します。オプション配列 [1,2,4,5,6] がある場合、製品AとC。

言い換えると、クエリ配列にないオプションを持たないすべての製品を取得する必要があります。方法は次のとおりです。

SELECT * from Product WHERE NOT EXISTS (
    SELECT product_id id, option_id opt from Product_option 
        WHERE id = Product.product_id AND opt NOT IN (1, 2, 4, 5, 6)
    )

結合を使用して明示的にこれを行うこともできEXISTSますが、私の意見では、クエリの方がアイデアをより明確に理解できます。

于 2012-12-14T13:17:39.443 に答える