База данных MySQL - дизайн производительности - PullRequest
0 голосов
/ 19 июня 2011

В настоящее время я занимаюсь редизайном сильно загруженного веб-сайта, и я был бы признателен за любое мнение по поводу конкретной проблемы дизайна базы данных.

Концепция заключается в том, чтобы хранить в БД ряд товаров (из них 500 тыс.). Каждый продукт может иметь ряд динамических свойств (около 1 КБ), а каждое свойство - количество предопределенных, но динамических значений (скажем, в среднем 10 для каждого свойства, т.е. около 10 КБ)

На данный момент это упрощенная структура БД:

Продукты (Таблица продуктов)

+--------+--------------+
| ProdID | Product Name |  
+--------+--------------+
| 1      | T-Shirt XYZ  |
+--------+--------------+
| 2      | Dress ABC    |
+--------+--------------+
| ...    | ...          |
+--------+--------------+
| 500000 | Something    |
+--------+--------------+

Определение свойств (таблица свойств) (содержит типы свойств)

+--------+--------------+
| PropID | Property Name|  
+--------+--------------+
| 1      | color        |
+--------+--------------+
| 2      | size         |
+--------+--------------+
| ...    | ...          |
+--------+--------------+
| 100    | Some Prop    |
+--------+--------------+

Определение значений свойств (таблица значений)

+-----------+--------+-------+
| PropValID | PropID | Value |  
+-----------+--------+-------+
|         1 |      1 | red   |
+-----------+--------+-------+
|         2 |      1 | blue  |
+-----------+--------+-------+
|         3 |      2 | m     |
+-----------+--------+-------+
|         4 |      2 | xl    |
+-----------+--------+-------+
|         5 |      2 | xxl   |
+-----------+--------+-------+
| ...       | ...    | ...   |
+-----------+--------+-------+
|      1000 |    100 | xyz   |
+-----------+--------+-------+

Таким образом, мы можем добавить любое количество свойств и значений в любой продукт. Таблица ниже содержит эту информацию.

Свойства продукта и значения (таблица ProdPropVal)

+--------+--------+--------+-----------+
| InfoID | ProdID | PropID | PropValID |
+--------+--------+--------+-----------+
|      1 |      1 |      1 |         1 |
+--------+--------+--------+-----------+
|      2 |      1 |      2 |         3 |
+--------+--------+--------+-----------+
|      3 |      2 |      1 |         2 |
+--------+--------+--------+-----------+
|      4 |      2 |      2 |         5 |
+--------+--------+--------+-----------+
| ...    | ...    | ...    |           |
+--------+--------+--------+-----------+

В приведенном выше примере мы знаем, что "футболка XYZ" имеет синий цвет, а его размер средний.

А теперь сложная часть ... если мы хотим найти все продукты, для которых установлены общие значения свойств (все продукты синего цвета и среднего размера), какой подход лучше всего подходит?

Мои идеи:

  1. Один раз найдите таблицу ProdPropVal для каждого PropValID и сравните результаты в коде. Это можно точно настроить, начав с самых редких PropValID и ограничив ProdID, используя WHERE ProdID IN (предыдущие идентификаторы) в следующих запросах.

  2. Используйте внутреннее соединение в таблице ProdPropVal для каждого требуемого PropValID. Что-то вроде: ВЫБЕРИТЕ ProdID ИЗ ProdPropVal ppv1 ВНУТРЕННЕЕ СОЕДИНЕНИЕ ProdPropVal ppv2 ВКЛ ppv1.ProdID = ppv2.ProdID ВНУТРЕННИЙ ПРИСОЕДИНЯЙТЕСЬ ProdPropVal ppv3 ВКЛ ppv1.ProdID = ppv3.ProdID ВНУТРЕННИЙ ПРИСОЕДИН. И ppv2.PropValID = 20 И ppv3.PropValID = 30 И ppv4.PropValID = 150

Пока это мои идеи. Тот факт, что планшет ProdPropVal имеет несколько миллионов строк, не оставляет места для ошибок.

Любое предложение приветствуется!

1 Ответ

1 голос
/ 19 июня 2011

Чтобы найти все товары синего цвета и среднего размера, я бы сделал это:

SELECT ProdID
  FROM ProdPropVal
  WHERE (PropID = 1 AND PropValID = 2)
  OR (PropID = 2 AND PropValID = 3)
  GROUP BY ProdID
  HAVING COUNT(*) = 2

Еще лучше, если PropValID уникален в таблице значений, тогда вы удалите столбец PropID из таблицы ProdPropVal и упростите запрос до этого:

SELECT ProdID
  FROM ProdPropVal
  WHERE PropValID IN (2, 3)
  GROUP BY ProdID
  HAVING COUNT(*) = 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...