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

 
     
 

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

oii
81
    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;


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

1
Просмотров: 282
     

Новости inPHP.org Новости inPHP.org
27.05.2010   Технические работы.
По техническим причинам возможны кратковременные перебои в работе сайта проекта в период с 27.05.2010 по 1.06.2010.
02.03.2010   Доступ участников к разработке тестирований.
В тестовом режиме запущен функционал, позволяющий участникам проекта разрабатывать собственные тестирования. Разработанные сообществом тестирования не имеют ограничений официальной аккредитации и в любое время доступны любому участнику.
19.02.2010   Введён общий рейтинг участника.
В рамках программы развития проекта введён параметр общего рейтинга участника. Соответствующие изменения внесены в правила проекта. Рейтинг - один из показателей, которые будут активно использоваться в готовящемся к запуску функционале. Первое из нововведений - доступ участников к системе разработки собственных тестирований и возможность неограниченного использования тестирований, разработанных сообществом, будет запущено в течение марта 2010 года.
 
Содействуют развитию Содействуют развитию
webdev
198
    webdev webdev
Константин
Специализации: 2
Участники проекта Участники проекта
ircphp
80
    ircphp ircphp

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

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

Специализации: 0
alistair
100
    alistair alistair
Александр
Специализации: 0
samion
100
    samion samion

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

УровеньПользователи
7481,6%
62157%
51585,2%
41665,4%
32909,5%
2411,3%
12889,4%
отсутствует184360,4%