Как мне создать вложенные категории в базе данных?

StackOverflow https://stackoverflow.com/questions/926175

  •  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 все, что вам нужно, это скрипт для обработки идентификатора таким образом, чтобы первая цифра представляла категорию верхнего уровня и так далее по мере продвижения вниз по иерархии

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top