Используйте MySQL для выбора атрибутов, похожих на Amazon SimpleDB - PullRequest
0 голосов
/ 01 августа 2011

Извините, я не мог придумать лучшего способа назвать это.В Amazon SimpleDB элемент может иметь несколько значений в одном столбце, поэтому можно выбрать только те элементы, которые имеют все требуемые атрибуты.

В MySQL, скажем, следующая таблица («Photo_Attributes») содержит неограниченное количество атрибутов для фотографий, которые содержатся в другой таблице («Photos»), и что эти две таблицы объединены Item_Number.

И, скажем, я хотел найти шляпу, цвет которой был красным, а размер был средним, в данном случае это ITEM_ID "ABC", а не "OPQ".

+-----+----------+--------+-----------+-------+  
| ID  | Item_ID  | Object | Attribute | Value |  
+-----+----------+--------+-----------+-------+  
|  1  |  ABC     | Hat    | Color     | Red   |  
+-----+----------+--------+-----------+-------+  
|  2  |  FGH     | Pants  | Color     | Blue  |  
+-----+----------+--------+-----------+-------+  
|  3  |  FGH     | Pants  | Size      | Large |  
+-----+----------+--------+-----------+-------+  
|  4  |  LMN     | Shirt  | Color     | Red   |  
+-----+----------+--------+-----------+-------+  
|  5  |  ABC     | Hat    | Size      | Med   |  
+-----+----------+--------+-----------+-------+  
|  6  |  LMN     | Shirt  | Size      | Med   |  
+-----+----------+--------+-----------+-------+  
|  7  |  OPQ     | Hat    | Color     | White |  
+-----+----------+--------+-----------+-------+  
|  8  |  OPQ     | Hat    | Size      | Med   |  
+-----+----------+--------+-----------+-------+  

Следующий запрос не даст результатов, поскольку каждая строка содержит только один атрибут и одно значение.

SELECT FROM Photo_Attributes WHERE OBJECT = 'hat' AND (Attribute = 'Color "AND Value =' Red ') AND (Attribute =' Size 'AND Value =' Med ');


И этот запрос будет производить больше строк, чем он должен(т.е. все красные и все элементы среднего размера).

ВЫБРАТЬ ИЗ Photo_Attributes ГДЕ ОБЪЕКТ = 'шляпа' И (Атрибут = 'Цвет' И Значение = 'Красный') ИЛИ (Атрибут = 'Size 'AND Value =' Med ');


Какой лучший способ написать это - и есть ли способ сделать это без использования JOIN в операторе SELECT?Мне интересно последнее, потому что запрос будет сгенерирован программно (в nodejs), а количество пар атрибут-значение может варьироваться от одного до нескольких.Я полагаю, что я мог бы также использовать вложенные запросы, отбирая из набора записей, но это кажется одинаково неэффективным.

1 Ответ

1 голос
/ 01 августа 2011
SELECT pa1.Item_ID
    FROM Photo_Attributes pa1
        INNER JOIN Photo_Attributes pa2
            ON pa1.Item_ID = pa2.Item_ID
                AND pa2.Attribute = 'Size'
                AND pa2.Value = 'Med'
    WHERE pa1.Object = 'Hat'
        AND pa1.Attribute = 'Color'
        AND pa1.value = 'Red'

Предполагая, что ваши пары имя / значение не будут перекрываться (например, у вас никогда не будет размера / красного или цвета / среднего), вы, вероятно, также можете сделать что-то подобное.

SELECT pa.Item_ID
    FROM Photo_Attributes pa
    WHERE pa.Object = 'Hat'
        AND pa.Attribute IN ('Size', 'Color')
        AND pa.Value IN ('Med', 'Red')
    GROUP BY pa.Item_ID
    HAVING COUNT(DISTINCT Value) = 2
...