Re: вопрос по проектированию
От: Flying Dutchman Украина  
Дата: 13.10.09 09:39
Оценка: 3 (1)
Здравствуйте, strelochnik, Вы писали:

S>Доброго времени суток всем!

S>Возник вот какой вопрос:
S>Есть электронный магазин, который торгует всякой всячиной. Есть в базе табличка Products, где содержится вся инфа по позициям.
S>Каждую категорию товара можно охарактеризовать общими для всех товаров свойствами (id, название, изображение, цена...), и свойствами, индивидуальными для каждой категории
S>(для телеков это диагональ, частота развертки..., для телефонов — наличие bluetooth, фотокамеры..., ну и т.д.) для этого у меня в таблице Categories есть поле detailsTable,
S>в которое кладется название таблицы с индивидуальными для категории параметрами, а в таблице Products — categoryID, ссылающееся на id категории. Вот не знаю, как
S>теперь из хранимки все это вытаскивать. на входе процедуры — id категории. Нужно на выходе получить некоторые поля из Products плюс все поля из соответветствующей этой категории
S>detailsTable. Не представляю, можно ли это сделать средствами SQL? Или придется в клиентском коде запросы генерить (что не хотелось бы)? И вообще, как такие задачи решаются, помогите советом плиз?

Такие задачи решаются при помощи паттерна проектирования баз данных Entity-Attribute-Value. Я только что закончил проектирование базы данных для Интернет-магазинов с использованием этого паттерна.

В простейшем виде структура БД для товаров выглядит примерно так:

1. Таблица Attribute(Attribute_Id [PK], Name, Type, ...)

содержит описания атрибутов (свойств), которые могут иметь товары. Например, это могут быть "Цвет" (для одежды), "Диагональ" (для телевизоров) и так далее. Атрибут имеет тип, например, текстовый или числовой.

2. Таблица Product(Product_Id [PK], Name, Description, Brand, ...)

содержит такие свойства товара, которые имеют все товары. Например, "Название товара", "Имя производителя" и т.д.

3. Таблица Product_Attribute(Product_Id [PK], Attribute_Id [PK], ...)

предназначена для моделирования связи "многие-ко-многим" между таблицами Product и Attribute. То есть какие атрибуты разрешено использовать для каких товаров + свойства конкретного атрибута для конкретного товара (например, в каком виде значения этого атрибута показываются пользователю).

4. Таблица Product_Attribute_Value(Product_ID [PK], Attribute_Id [PK], Attribute_Value)

содержит конкретные значения атрибутов товаров. Я использую SQL Server 2008 и столбец Attribute_Value имеет тип sql_variant. Это позволяет хранить в одном и том же столбце значения различных типов. При этом нужно следить, чтобы товарам не были присвоены значения атрибутов, которые не разрешены для этого товара. (Это можно реализовать при помощи триггера, который при вставке данных проверяет их правильность на основе данных из таблицы Product_Attribute).

Атрибуты и их значения для конкретного товара можно извлечь простым запросом:
select attr.Name as Attribute_Name,
       attr_val.Value as Attribute_Value
  from Attribute attr inner join Product_Attribute_Value attr_val
    on attr.Attribute_Id = attr_val.Attribute_Id
  where attr_val.Product_Id = <...>


Значение типа sql_variant потом можно преобразовать в нужный тип в программе-клиенте.

Кроме этого, можно легко искать товары, то есть выполнять запросы типа "Найти все товары где Цвет=Красный и Размер=XL". Для этого используется простой запрос с использованием реляционного деления.

Конечно, это очень упрощенная схема. На самом деле все выглядит сложнее сложнее. Например, в моей базе более 30 таблиц предназначено для хранения метаданных — описаний атрибутов и их значений. Атрибуты имеют различные типы (String, int и так далее) и каждому типу соответствует своя таблица. Кроме этого, наша БД многоязыковая и для значений многих атрибутов хранятся также их переводы на все используемый языки и т.д.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.