Как создать вложенные категории в базе данных? - PullRequest
9 голосов
/ 29 мая 2009

Я создаю веб-сайт с видео, где будут вложены категории:

например. Программирование-> Язык C -> MIT Видео -> Видео 1 Программирование -> Язык C -> Стэнфордское видео -> Видео 1 Программирование -> Python -> Видео 1

Эти категории и подкатегории будут создаваться пользователями на лету. Мне нужно будет показать их, поскольку люди создают их в форме навигационного меню, чтобы люди могли легко просматривать коллекции.

Может ли кто-нибудь помочь мне с созданием такой базы данных?

Ответы [ 6 ]

12 голосов
/ 29 мая 2009

Составьте таблицу категорий со следующими полями:

  • 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
8 голосов
/ 29 мая 2009

Кассной сказал:

Вы должны использовать либо вложенные множества, либо модели типа «родители-потомки».

Я использовал для реализации их обоих. Что я мог сказать, это:

Используйте архитектуру вложенного множества, если ваша таблица категорий не меняется часто, потому что в предложении select это быстро, и только с одним запросом вы можете получить всю ветвь иерархии для данной записи. Но в предложении вставки или обновления требуется больше времени, чем родительской дочерней модели, чтобы обновить левый и правый (или нижний и верхний в примере ниже).

Еще один момент, довольно тривиальный, я должен признать, но:
Очень трудно изменить иерархию вручную непосредственно в базе данных (это может произойти во время разработки). Поэтому убедитесь, что сначала реализован интерфейс для воспроизведения с вложенным набором (смена родительского узла, перемещение узла ветвления, удаление узла или всей ветви и т. Д.)

Вот две статьи на эту тему:

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

5 голосов
/ 29 мая 2009

Из примера в вашем вопросе выглядит так, как будто вы хотите, чтобы у данной категории было несколько родителей (например, «MIT Videos -> Video 1 Programming», а также «Video -> Video 1 Programming»). "), в этом случае простого добавления столбца ParentID будет недостаточно.

Я бы порекомендовал создать две таблицы: простую таблицу Categories со столбцами CategoryID и CategoryName и отдельную таблицу CategoryRelationships со столбцами ParentCategoryID и ChildCategoryID. Таким образом, вы можете указать столько родительско-дочерних отношений, сколько захотите для любой конкретной категории. Можно даже использовать эту модель, чтобы иметь двойные отношения, в которых две категории являются родителями и потомками друг друга одновременно. (Вдобавок ко всему, я не могу придумать, как эффективно использовать этот сценарий, но, по крайней мере, он показывает, насколько гибка модель.)

4 голосов
/ 29 мая 2009

Вы должны использовать либо 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 проще запрашивать, но сложнее его обновить и сложнее построить древовидную структуру.

0 голосов
/ 28 июля 2009

Лучший способ сохранить parent_id таблицы - поместить ее в ID * 1001 например *

100000 Программирование 110000 C Язык 111000 Видео 1 Программирование 111100 C Язык 111110 Стэнфордское видео

и т.д.

0 голосов
/ 29 мая 2009

То, что вам нужно, это базовые отношения родитель-ребенок:

Category (ID: int, ParentID: nullable int, Name: nvarchar(1000))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...