Разделы публикаций

 
     
 

Иерархические структуры данных

oii
83
    oii oii

Специализации: 0

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

Основные запросы, при работе с иерархическим списком:


  • получения потомков элемента;

  • получения уровня вложенности элемента;

  • получения полного пути от элемента до корня иерархии;

  • операции вставки, удаления, перемещения элемента и его потомков;

  • получение непосредственных потомков/предков.




Cамым очевидным решением является создание в таблице поля, с указанием на первичный ключ предка данного элемента.
Структура таблицы при этом выглядит следующим образом:

CREATE TABLE `categories` (
`id` int(10) unsigned NOT NULL default '0',
`name` varchar(100) default NULL,
`parent` int(10) unsigned default NULL,
PRIMARY KEY USING BTREE (`cat_id`)
) ;

Но у этого метода есть существенные недостатки:

  • необходимость рекурсивных запросов для получения полного пути от произвольного элемента до корня дерева;

  • сложность вычисления уровня вложенности произвольного элемента;

  • сложность получения всех (в том числе и не прямых) потомков данного узла.




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

Чтобы свести эти недостатки к минимуму необходимо добавить в структуру информацию о полном пути и уровне.

В дополнение к первоначальной таблице, создать вспомогательную таблицу, содержащую два поля: Id элемента и Id всех его предков.


CREATE TABLE `parents` (
`cat_id` int(10) unsigned default NULL,
`par_id` int(10) unsigned default NULL
) ;


Подобная схема легко позволяет получить любую информацию об иерархических элементах одним запросом.

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

Информацию об уровне заданного элемента можно узнать, получив количество его предков:


SELECT count(cat_id) FROM parents WHERE cat_id =7;


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

3
Просмотров: 916
     

Новости inPHP.org Новости inPHP.org
30.12.2011   С наступающим Новым Годом!
Команда inPHP.org поздравляет всех посетителей сайта проекта с наступающим Новым Годом! Вероятно, многие участники проекта заметили некоторое затишье в уходящем году. Поверьте, в следующем всё будет несколько иначе!
31.12.2010   С Новым Годом!
Уважаемые коллеги, коллектив проекта inphp.org искренне поздравляет вас с наступающим Новым Годом!
27.05.2010   Технические работы.
По техническим причинам возможны кратковременные перебои в работе сайта проекта в период с 27.05.2010 по 1.06.2010.
02.03.2010   Доступ участников к разработке тестирований.
В тестовом режиме запущен функционал, позволяющий участникам проекта разрабатывать собственные тестирования. Разработанные сообществом тестирования не имеют ограничений официальной аккредитации и в любое время доступны любому участнику.
 
Содействуют развитию Содействуют развитию
Участники проекта Участники проекта
olegator2k
60
    olegator2k olegator2k

Специализации: 0
dizzyman
140
    dizzyman dizzyman
Вербицкий Егор
Специализации: 0
dennsp
100
    dennsp dennsp

Специализации: 0
alexus3d
80
    alexus3d alexus3d

Специализации: 0
panda
100
    panda panda

Специализации: 0
 
Статистика проекта Статистика проекта
Всего пользователей: 3648
Из них аккредитовано: 1468
Были сегодня: 2

УровеньПользователи
7742%
62376,5%
52075,7%
41945,3%
336510%
2401,1%
13509,6%
отсутствует218059,8%