У вас есть базовая таблица ПРОДУКТОВ. В этой таблице вы можете указать базовую цену товара.
У вас есть базовая таблица ATTRIBUTES. Просто список возможных атрибутов, которые можно применить к вашим продуктам. Обычно это сложнее, чем простой список, то есть обычно он также связан с типом продукта. Другими словами, не все атрибуты применимы ко всем продуктам. Таким образом, некоторые системы также имеют таблицу PRODUCTTYPE и таблицу PRODUCTTYPEATTRIBUTES. И некоторые атрибуты применимы, только если действуют другие атрибуты. Смотрите пример стула ниже. Там это может стать очень сложным.
У вас есть таблица привязки, где ПРОДУКТ связан с одним или несколькими АТРИБУТАМИ. В этой таблице хранится цена дополнения атрибута.
Стоимость продукта - это его базовая цена плюс сумма цен его атрибута (ов). Стул = 100. Кожа = 75 апгрейд. Латунные гвозди = 25 улучшений. Кожаное кресло с латунными гвоздями = 200. Но вам не понадобятся медные гвозди, если у вас нет кожаного апгрейда. Так что кресло + латунные гвозди - не реальный вариант. Некоторые базы данных применяют такие правила в своей структуре. Другие делают это во фронтэнде. Это может стать довольно сложным.
Но эта структура из трех таблиц позволяет использовать несколько атрибутов для каждого продукта. Клиент может заказать базовый продукт или базовый продукт с одним или несколькими атрибутами, связанными с продуктом в вашей таблице PRODUCTATTRIBUTES.
Уникальные составные индексы в таблице PRODUCTATTRIBUTES (productid, attributeid) не позволят пользователю применять атрибут более одного раза: стул + кожа + кожа + латунные гвозди будут невозможны, и поэтому вы также запрещаете пользователю от того, что для одного и того же продукта обновление кожи стоит 100 в одном ряду и 125 в другом.