sql >> データベース >  >> RDS >> Mysql

SQLでフィルターシステムを実装する方法は?

    entity-attribute-value あなたが提案するモデルは、このシナリオに適合する可能性があります。

    フィルタリングクエリに関しては、EAVモデルを使用すると、クエリの能力が大幅に犠牲になることを理解する必要があります。そのため、これは非常に難しい場合があります。ただし、問題に取り組むためのこの1つの方法:

    SELECT    stuff.id 
    FROM      stuff 
    JOIN      (SELECT    COUNT(*) matches
               FROM      table
               WHERE     (`key` = X1 AND `value` = V1) OR 
                         (`key` = X2 AND `value` = V2) 
               GROUP BY  id
              ) sub_t ON (sub_t.matches = 2 AND sub_t.id = stuff.id)
    GROUP BY  stuff.id;
    

    このアプローチのエレガントでない機能の1つは、sub_t.matches = 2で一致すると予想される属性/値のペアの数を指定する必要があることです。 。 3つの条件がある場合、sub_t.matches = 3を指定する必要があります。 、など。

    テストケースを作成しましょう:

    CREATE TABLE stuff (`id` varchar(20), `key` varchar(20), `value` varchar(20));
    
    INSERT INTO stuff VALUES ('apple',  'color',  'red');
    INSERT INTO stuff VALUES ('mango',  'color',  'yellow');
    INSERT INTO stuff VALUES ('banana', 'color',  'yellow');
    
    INSERT INTO stuff VALUES ('apple',  'taste',  'sweet');
    INSERT INTO stuff VALUES ('mango',  'taste',  'sweet');
    INSERT INTO stuff VALUES ('banana', 'taste',  'bitter-sweet');
    
    INSERT INTO stuff VALUES ('apple',  'origin',  'US');
    INSERT INTO stuff VALUES ('mango',  'origin',  'MEXICO');
    INSERT INTO stuff VALUES ('banana', 'origin',  'US');
    

    クエリ:

    SELECT    stuff.id 
    FROM      stuff 
    JOIN      (SELECT    COUNT(*) matches, id
               FROM      stuff
               WHERE     (`key` = 'color' AND `value` = 'yellow') OR 
                         (`key` = 'taste' AND `value` = 'sweet')
               GROUP BY  id
              ) sub_t ON (sub_t.matches = 2 AND sub_t.id = stuff.id)
    GROUP BY  stuff.id;
    

    結果:

    +-------+
    | id    |
    +-------+
    | mango |
    +-------+
    1 row in set (0.02 sec)
    

    次に、color=yellowを使用して別の果物を挿入しましょう およびtaste=sweet

    INSERT INTO stuff VALUES ('pear', 'color', 'yellow');
    INSERT INTO stuff VALUES ('pear', 'taste', 'sweet');
    INSERT INTO stuff VALUES ('pear', 'origin', 'somewhere');
    

    同じクエリが返されます:

    +-------+
    | id    |
    +-------+
    | mango |
    | pear  |
    +-------+
    2 rows in set (0.00 sec)
    

    この結果をorigin=MEXICOのエンティティに制限する場合 、別のORを追加する必要があります 条件を設定し、sub_t.matches = 3を確認します 2の代わりに 。

    SELECT    stuff.id 
    FROM      stuff 
    JOIN      (SELECT    COUNT(*) matches, id
               FROM      stuff
               WHERE     (`key` = 'color' AND `value` = 'yellow') OR 
                         (`key` = 'taste' AND `value` = 'sweet') OR 
                         (`key` = 'origin' AND `value` = 'MEXICO')
               GROUP BY  id
              ) sub_t ON (sub_t.matches = 3 AND sub_t.id = stuff.id)
    GROUP BY  stuff.id;
    

    結果:

    +-------+
    | id    |
    +-------+
    | mango |
    +-------+
    1 row in set (0.00 sec)
    

    すべてのアプローチと同様に、EAVモデルを使用する場合には特定の長所と短所があります。アプリケーションのコンテキストでトピックを広範囲に調査するようにしてください。 Cassandra などの代替のリレーショナルデータベースを検討することもできます。 、 CouchDB MongoDB Voldemort HBase SimpleDB または他のキーバリューストア。



    1. Python3.x用のMySQL-dblib?

    2. リモートMysqlアクセス

    3. 名前付きパラメーターの順序は、MySql .Netデータプロバイダーにとって意味がありますか?

    4. 結合条件でISNULLまたはISNOTNULLを使用する-理論上の質問