Как мне создать вложенные категории в базе данных?
-
06-09-2019 - |
Вопрос
Я создаю веб-сайт с видеороликами, где категории будут вложенными:
например ,Программирование-> Язык C - > Видеоролики MIT -> Видео 1 Программирование -> Язык C -> Видеоролик Stanford - > Видео 1 Программирование -> Python -> Видео 1
Эти категории и подкатегории будут создаваться пользователями "на лету".Мне нужно будет показывать их по мере их создания пользователями в виде навигационного меню, чтобы люди могли легко просматривать коллекцию.
Не мог бы кто-нибудь, пожалуйста, помочь мне с тем, как я могу приступить к созданию такой базы данных?
Решение
Сказал Квассной :
Вам следует использовать либо вложенные наборы, либо родительско-дочерние модели.
Раньше я реализовывал их оба.Что я мог бы сказать, так это:
Используйте архитектуру вложенного набора, если ваша таблица категорий меняется нечасто, потому что в предложении select это происходит быстро и всего одним запросом вы можете получить всю ветвь иерархии для данной записи.Но в предложении insert или update требуется больше времени, чем в родительской дочерней модели, для обновления левого и правого (или нижнего и верхнего в примере ниже) полей.
Еще один момент, довольно тривиальный, я должен признать, но:
Очень сложно изменить иерархию вручную непосредственно в базе данных (это может произойти во время разработки).Итак, обязательно сначала реализуйте интерфейс для работы с вложенным набором (изменение родительского узла, перемещение узла ветви, удаление узла или всей ветви и т.д.)
Вот две статьи на эту тему:
Последнее, я не пробовал, но я где-то читал, что во вложенной таблице наборов может быть более одного дерева, я имею в виду несколько корней.
Другие советы
Создайте таблицу категорий со следующими полями:
- CategoryID - Целое число
- CategoryName - Строка/Varchar/Что угодно
- ParentID - Целое число
Затем ваш ParentID будет ссылаться обратно на CategoryID своего родителя.
Пример:
CategoryID CategoryName ParentID
---------------------------------
1 Dog NULL
2 Cat NULL
3 Poodle 1
4 Dachsund 1
5 Persian 2
6 Toy Poodle 3
Из примера в вашем вопросе похоже, что вы хотели бы, чтобы для данной категории было возможно иметь несколько родительских элементов (например, "MIT Videos -> Video 1 Programming", а также "Video -> Video 1 Programming"), и в этом случае простого добавления столбца ParentID было бы недостаточно.
Я бы рекомендовал создать две таблицы:простая таблица категорий со столбцами CategoryID и CategoryName и отдельная таблица CategoryRelationships со столбцами ParentCategoryID и ChildCategoryID.Таким образом, вы можете указать столько связей родитель-потомок, сколько захотите, для любой конкретной категории.Используя эту модель, можно было бы даже создать двойственную взаимосвязь, при которой две категории одновременно являются родительскими и дочерними друг для друга.(Навскидку я не могу придумать, как лучше всего использовать этот сценарий, но, по крайней мере, он иллюстрирует, насколько гибкой является модель.)
Вы должны использовать либо то, либо другое nested sets
или parent-child
Модели.
Parent-child
:
typeid parent name 1 0 Buyers 2 0 Sellers 3 0 Referee 4 1 Electrical 5 1 Mechanic
SELECT *
FROM mytable
WHERE group IN
(
SELECT typeid
FROM group_types
START WITH
typeid = 1
CONNECT BY
parent = PRIOR typeid
)
будет отбирать всех покупателей в Oracle
.
Nested sets
:
typeid lower upper Name 1 1 2 Buyers 2 3 3 Sellers 3 4 4 Referee 4 1 1 Electrical 5 2 2 Mechanic
SELECT *
FROM group_types
JOIN mytable
ON group BETWEEN lower AND upper
WHERE typeid = 1
отберет всех покупателей в любой базе данных.
Видишь этот ответ для получения более подробной информации.
Nested sets
его проще запрашивать, но его сложнее обновлять и сложнее построить древовидную структуру.
Что вам нужно, так это базовые отношения родитель-потомок:
Category (ID: int, ParentID: nullable int, Name: nvarchar(1000))
Лучший способ сохранить parent_id таблицы - вложить его в идентификатор например
100000 Программирование 110000 Язык C 111000 Видео 1 Программирование 111100 Язык C 111110 Видео из Стэнфорда
etc..so все, что вам нужно, это скрипт для обработки идентификатора таким образом, чтобы первая цифра представляла категорию верхнего уровня и так далее по мере продвижения вниз по иерархии