LINUX.ORG.RU

Проектирование таблиц в БД

 , ,


1

4

День добрый сообщество. Я с таким вопросом , есть задача спроектировать бд, и есть функционал где есть категории и подкатегории, и вот я проектировал это через две таблицы, первая это таблица категорий id, name, ну а вторая таблица id,parent_id,name, ну думаю понятно ссылка parent_id, это ссылка на id первой таблицы. Но мне советуют еще вариант снести все в одну таблицу, вида id, parent_id, name, и тут как выходит у категорий так как над ними родителя нету будет поле parent_id null в случае если одной талицы, а вот для подкатегорий уже парент id , будет браться с этой же таблицы, но именно id категории . Схема вроде хитрая, но я сторонник первого варианта так как он более прозрачен и гибок, просто если подкатегориям уже добавлять непосредственно элементы, то это будет три таблицы, либо срач в той одной, могли бы вы описать минусы и может возможные плюсы способа с одной таблицей.



Последнее исправление: Berdin (всего исправлений: 1)

я тоже сторонник первого варианта, ибо для каждой сущности - своя таблица. подписался.

bvn13 ★★★★★
()

Схема вроде хитрая

самая обычная

просто если подкатегориям уже добавлять непосредственно элементы

Сам спросил, сам ответил. Тебе же на каждый уровень иерархии нужно плодить таблицу.

Hater ★★
()
Последнее исправление: Hater (всего исправлений: 1)

Если у категорий и подкатегорий одинаковые поля (name и т.п.), то нет смысла хранить их в разных таблицах.

Wolfram
()

Второй вариант например используется в WordPress, только для корневых категорий parent_id = 0 а не null. Брат жив (:
По гибкости вроде особой разницы нет. Подозреваю что выбор сведётся к идеологической правильности того или иного подхода («Кошерно-ли выносить в отдельную таблицу связи между элементами другой таблицы?»).

P.S. в первом варианте в элемента может быть несколько родительских элементов, это может быть полезным.

MrClon ★★★★★
()
Ответ на: комментарий от bvn13

Это же одинаковые сущности, отличаются только тем, есть ли у них родитель.

Из второй схемы можно быстро запросить категории или подкатегории(where parent_id is null), а вот из первой схемы нужно будет лепить union, если понадобятся оба типа.

disarmer ★★★
()
Ответ на: комментарий от bvn13

Можно-ли считать связь между двумя сущностями («кошки» входит в «животные») отдельной сущностью?

MrClon ★★★★★
()
Ответ на: комментарий от Hater

Тебе же на каждый уровень иерархии нужно плодить таблицу.

[code]
cat_id cat_parent
1 null
2 1
3 2
[/code]
Первая категория корневая, вторая входит в первую, третья входит во вторую.

P.S. почему лоркод не работает?

MrClon ★★★★★
()
Последнее исправление: MrClon (всего исправлений: 1)
Ответ на: комментарий от disarmer

Согласен, именно поэтому, думаю, следует выбирать на основании задач и дальнейших действий с данными. Говорят, что БД нужно проектировать «от отчетов».

bvn13 ★★★★★
()
Ответ на: комментарий от MrClon

можно, если нужен этот слой абстракции данных.

bvn13 ★★★★★
()
Ответ на: комментарий от bvn13

Реляционная модель данных предполагает при проектировании БД отталкиваться от данных и их связей, а не от текущих потребностей. Потребности могут меняться, а реляционная модель придумана что-ьы обеспечить максимальную универсальность.

Но это так, идеология.

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Второй вариант например используется в WordPress, только для корневых категорий parent_id = 0 а не null.

Лучше использовать NULL ну и ставить связь на id, чтобы мусора небыло в системе.

По теме - используй 1 таблу

kiotoze ★★★★
()

Делал и так и так, в итоге выжил первый вариант, так как легче расширяется.

ilovewindows ★★★★★
()

Зависит от физической природы категорий/подкатегорий. Если подкатегория - это заведомо последнее разбиение (то бишь мельче уже нельзя физически) - тогда первый вариант, потому что категории подкатегории - разные сущности и разные таблицы. Иначе, когда появляются новые подкатегории (или вообще меняется иерархия) - тогда все категории - это одна сущность с характеристикой «уровень» и «родитель», соответственно, и таблица одна.

Если, к примеру, это страна/район или вуз/факультет, то понятно, что подрайончиков у района или подфакультетиков у факультета не бывает в принципе. А если это комплектующие, скажем, то там деление очень условное, и у устройств хранения/внутренних накопителей может появиться разделение SSD/HDD и т.п., а то и вообще разделятся на хранение/hdd и хранение/sdd.

E ★★★
()

если будет максимум один уровень вложенности то все равно какой вариант. в других случаях можешь посмотреть в сторону mptt

anonymous
()
Ответ на: комментарий от E

А если природа категорий/подкатегорий и непосредственно элементов это группы скилов, подгруппы, и сами скилы?

Berdin
() автор топика
Ответ на: комментарий от Berdin

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

E ★★★
()
Ответ на: комментарий от bvn13

Говорят, что БД нужно проектировать «от отчетов».

Не слушай их, плохому научат.

Почитай про нормальные формы, для каких целей каждая необходима и т.д.

habamax ★★★
()

Схема вроде хитрая

Ничего хитрого один из стандартных способов хранения иерархии parent-child.

Еще есть вариант с 2-мя таблицами — в одной сущности (категории/подкатегории/подподкатегории...) в другой отношения между ними id, parent_id

habamax ★★★
()

Для деревьев nested sets хорошо использовать. Хорошая производительность при извлечении данных, можно удобно вытягивать все подкатегории из любого места дерева.

Black_Roland ★★★★
()
Ответ на: комментарий от Black_Roland

Для деревьев nested sets хорошо использовать. Хорошая производительность при извлечении данных, можно удобно вытягивать все подкатегории из любого места дерева.

Вот только на запись и перемещение большие накладные расходы. Быстрое же вытягивание поддерева доступно и для closure tables.

Кстати говоря, вот краткий обзор вариантов: http://stackoverflow.com/questions/4048151/what-are-the-options-for-storing-h...

static_lab ★★★★★
()
Ответ на: комментарий от static_lab

Вот только на запись и перемещение большие накладные расходы.

Да, это правда. Но для категорий запись требуется пару раз в год.

Black_Roland ★★★★
()

foreign key NULL - это нормальная ситуация. Остается только понять что у тебя с набором полей для категорий подкатегорий, не только же имя.

Для первого варианта у тебя получится железобетонная структура Категория -> Подкатегория, зато расширяемость атрибутов будет безгеморройная, да и выборки.

Для второго варианта у тебя будет гибкая структура, но специфичные для уровня атрибуты будут NULL в других уровнях, а выборка элемента третьего уровня будет веселом фаршем из join, но ты можешь добавить уровень, тогда согласованность БД придется обеспечивать триггерами всякими.

В общем РСУБД для прибитых к полу структур данных, так что бери монгу и вперед.

anonymous
()
Ответ на: комментарий от Black_Roland

Но для категорий запись требуется пару раз в год.

Если я правильно понял задачу, то в одной таблице в данном случае предполагается хранить как категории, так и подкатегории. При этом структура Nested Sets предполагает обновление поддерева при любом инсерте. Следовательно, добавление подкатегории тоже будет перестраивать таблицу.

Однако, если иерархия категорий действительно меняется очень редко, а контент категорий размещается в отдельной связанной таблице, то это может иметь смысл.

static_lab ★★★★★
()

Кажется есть недопонимание. У варианта с двумя таблицами есть два подварианта:
1) Первая таблица для категорий первого уровня, вторая для категорий второго уровня (подкатегорий). На мой взгляд это годится только для весьма жёстких иерархий.
2) В первой таблице хранятся категории (любого уровня вложенности), а во второй связи между категориями, которые собственно определяют структуру. Вариант очень гибкий (у категории может быть несколько родителей например, да и вообще можно создавать произвольные графы), но нужно-ли это в данном случае?

MrClon ★★★★★
()
Ответ на: комментарий от anonymous

В общем РСУБД для прибитых к полу структур данных, так что бери монгу и вперед.

Я уж думал никто не предложит, думал перевелись идиоты на земле ЛОРовской, ан нет, не перевелись.

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Я уж думал никто не предложит, думал перевелись идиоты на земле ЛОРовской, ан нет, не перевелись.

есть контраргументы в данном случае?

anonymous
()
Ответ на: комментарий от anonymous

А есть аргументы в пользу замены проверенного, распространённого, привычного и надёжного инструмента?
«Я вижу два способа сделать это через РСУБД, какой лучше?» это не аргумент против РСУБД.

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

«Я вижу два способа сделать это через РСУБД, какой лучше?» это не аргумент против РСУБД.

ну это ежели у него структура фиксированная, что таки и есть usecase для реляционной модели - полностью формализованная предметная область. Если же черт его знает чего там заказчик на самом деле хочет, при этом нет и не предвидится требований для ACID, то лучше не мучать себя и использовать специально для этого разработанные инструменты.

anonymous
()
Ответ на: комментарий от anonymous

Тут выше уже писали как задать в РСУБД деревья и вообще произвольные направленные графы. Какая ещё тебе нужна гибкость, анон?

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Тут выше уже писали как задать в РСУБД деревья и вообще произвольные направленные графы. Какая ещё тебе нужна гибкость, анон?

Да, действительно, давай навернем 100500 императивных ограничений, убъем производительность, сделаем логику неочевидной, зато у нас останется наш проверенный веками инструмент.

Я не пытаюсь запихнуть документо-ориентированные СУБД в каждую щель, а просто предлагаю. Если никаких препятствий нет - выкидываем РСУБД и берем что удобнее.

anonymous
()
Ответ на: комментарий от anonymous

Какие ограничений? Простейшая однотабличная схема достаточна для деревьев, а категории как-раз и предполагают деревья.
Да, обрабатывать такое дерево придётся рекурсией. Ужас как сложно...

Я не пытаюсь запихнуть документо-ориентированные СУБД в каждую щель, а просто предлагаю. Если никаких препятствий нет - выкидываем РСУБД и берем что удобнее.

Это и называется «засовывать в каждую щель». Правильный подход: если никаких препятствий нет — продолжаем использовать РСУБД и не паримся.

MrClon ★★★★★
()
Ответ на: комментарий от MrClon

Простейшая однотабличная схема достаточна для деревьев, а категории как-раз и предполагают деревья.

Да, обрабатывать такое дерево придётся рекурсией

Ну смотри: табличка table {id, parent_id, data}, запрос для получения всех подкатегорий третьего(0 - корень) уровня вложенности получается уже каким-то не особо удобным, да чего там, совсем уж костыльным.

А теперь такая table {id,parent_id, depth, data}. Запрос упрощается, зато вставка нового элемента требует триггера на определение depth.

И это все при при условии что data у нас всегда одинаковая. Если разная, то на уровне БД придется определять и эту логику.

В монге у нас останется только неудобство от 1го пункта. Но нет, мы оставим РСУБД, патамушта дедынормализовали!!

anonymous
()
Ответ на: комментарий от static_lab

Столько коментов и сложн выбрать в итоге вариант, толи в две таблицы толи в одну.

Berdin
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.