SQL

Как реализовать архитектуру БД?

Добрый вечер. Только осваиваю SQL. Подскажите пожалуйста как лучше реализовать архитектуру базы данных.

Имею - Бренд (например Samsung), у брендов есть подкатегории (например "планшеты", "телефоны" и. т. д.), у подкатегорий в свою очередь есть свои подкатегории (например в случае с телефонами "1 сим карта", "2 сим карты" и т. д.). При этом некоторые подкатегории брендов далее не имеют потомков (например Samsung - планшет не имеет своих подкатегорий).

Так вот как лучше делать таблицы в БД? Делать например таблицы:
1) "brands" (в которой делать поля brand_id, brand_name (Например brand_id = 1, brand_name = Samsung).
2) "category" - в которой делать поля category_id, category_name, category_brand_id ( category_id = 1, category_name = Телефоны, category_brand_id = 1 (т. е. внешний ключ на таблицу brands)
3) "podcategory" - в которой делать поля podcategory_id, podcategory_name, parent_category_id (podcategory_id = 1, podcategory_name = 1 сим карта, parent_category_id = 1 (внешний ключ на таблицу category).

Спасибо!
PA
Pyctem Anetov
521
1. Категория - это отдельная сущность, которая не привязана к бренду (категория "смартфон" не зависит от того, какой фирмы этот смартфон). Каждый товар должен иметь brand_id и category_id. Категория не должна ссылаться на бренд. Связь категорий и брендов реализуется через товары. Если же нужны связи, на зависящие от товаров, то это реализуется отдельной таблицей, содержащей brand_id и category_id (стандартная реализация связи многие-ко-многим)

2. Не надо делать отдельную таблицу подкатегорий. Категории образуют дерево. И для хранения деревьев в реляционной СУБД придумано несколько эффективных способов. Простейший вариант - ссылка на родительскую категорию (запись в таблице category имеет поле category_id - id родительской записи в той же таблице categoty, null - категория верхнего уровня). Немного сложнее (но удобнее в выборке) - Nested Set (в рунете полно статей с примерами реализации).

3. "1 сим-карта", "2 сим-карты" - это не категории, а атрибуты (характеристики конкретного товара). Такие же, как цвет смартфона или диагональ экрана. Для атрибутов удобнее использовать EAV (опять же - в рунете достаточно много статей на эту тему), а вот списки доступных для товаров атрибутов должны быть привязаны к категориям (смартфон не может иметь атрибут "диаметр шин"). Т. е. должны быть таблицы, описывающие наборы допустимых атрибутов (и списки допустимых значений этих атрибутов - если атрибут может принимать фиксированное число значений).
НБ
Николай Башкиров
73 871
Лучший ответ
Pyctem Anetov Спасибо за ответ!

Т. е. я правильно понял, (возьмём теперь в пример ГСМ) что если например у меня есть бренды Shell, Total - для них я делаю таблицу brands (c полями brands_id и brands_name), у них есть категории "Гидравлические" и "дизельные" - для них я делаю таблицу category (с полями category_id, category_name и parent_id). Дальше например только у бренда Total есть категория "смазочные материалы" (эта категория записана в таблице category параметром category_id = 6, и parent_id = null ) и эта категория имеет подкатегорию "масла для цепей". Так вот для подкатегории "масла для цепей" я не делаю отдельную таблицу, а заношу её в таблицу category и в поле parent_id = 6 (т. к. запись "смазочные материалы" в этой же таблице записана как category_id = 6).