В результате разработки информационного новостного портала появилась алгоритмическая проблема взаимодействия с MySQL.
Рубрикация организована следующим образом (таблица: важнейшие поля):
TABLE rubric (рубрики): rubric_id, rubric_parent (id родительской рубрики)
TABLE rubric_article (таблица связей рубрик со статьями): rubric_article_id, rubric_id (id рубрики), article_id (id статьи)
TABLE article (статьи): article_id, article_type (тип(раздел) статей)
TABLE type (типs(разделs) статей): type_id
Т.е. иерархия рубрик устроена "линейно": каждая рубрика знает только своего родителя. У корневой рубрики родитель 0.
Необходимо при входе в раздел статей (за него отвечает type_id) выводить иерархически рубрики, в которых есть статьи, относящиеся к данному разделу (по article_type).
Выводить всё это надо не в виде дерева, а поступенчато: -> раздел -> темы уровня 0 (с родителем 0) -> темы уровня 1 (с выбранным родителем) и т.п. Так можно опускаться на произвольную глубину.
Проблема заключается в том, что некоторые разделы могут непосредственно не содержать статьи, а содержать их в своих подрубриках. Узнать при этом все рубрики заданного уровня (т.е. по заданному родителю), содержащие где-то в глубоких своих подрубриках-потомках статьи из данного раздела — задача нетривиальная.
Сайт планируется быть активно посещаемым, поэтому большое кол-во обращений к базе каждым пользователем (а оно в тривиальном решении будет сильно расти с каждой новой рубрикой) недопустимо.
Какие будут мысли, коллеги?
A>Необходимо при входе в раздел статей (за него отвечает type_id) выводить иерархически рубрики, в которых есть статьи, относящиеся к данному разделу (по article_type).
A>Выводить всё это надо не в виде дерева, а поступенчато: -> раздел -> темы уровня 0 (с родителем 0) -> темы уровня 1 (с выбранным родителем) и т.п. Так можно опускаться на произвольную глубину.
содержащие где-то в глубоких своих подрубриках-потомках статьи из данного раздела — задача нетривиальная. A>Сайт планируется быть активно посещаемым, поэтому большое кол-во обращений к базе каждым пользователем (а оно в тривиальном решении будет сильно расти с каждой новой рубрикой) недопустимо. A>Какие будут мысли, коллеги?
Мысль номер 1 — передалать структуру
Мысль номер 2: A>Проблема заключается в том, что некоторые разделы могут непосредственно не содержать статьи, а содержать их в своих подрубриках. Узнать при этом все рубрики заданного уровня (т.е. по заданному родителю),
Как это он может не содаржать статей , если единсвенная связь с раздела у тебя в таблице статей?
Либо я запутался в твоем объеяснении, так как вижу только три сущности: Статья, Рубрикатор (статья в нескольких рубриках) , Разделы статей
давай опиши вот в этих понятиях задачу.
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Откровенно говоря, не приходит в голову что-то более удобное..
dad>Мысль номер 2: A>>Проблема заключается в том, что некоторые разделы могут непосредственно не содержать статьи, а содержать их в своих подрубриках. Узнать при этом все рубрики заданного уровня (т.е. по заданному родителю),
dad>Как это он может не содаржать статей , если единсвенная связь с раздела у тебя в таблице статей? dad>Либо я запутался в твоем объеяснении, так как вижу только три сущности: Статья, Рубрикатор (статья в нескольких рубриках) , Разделы статей
dad>давай опиши вот в этих понятиях задачу.
Всё правильно. Вот пример.
Рубрика А содержит рубрики А1 и А2. Рубрики А1 и А2 содержат статьи. Об этом содержится записи в "Рубрикаторе" (А1_id | ArticleX1_id; А2_id | ArticleX2_id. Однако никаких упоминаний о рубрике А в "Рубрикаторе" нет, т.к. непосредственно она не содержит статей, но её подрубрики статьи содержат. Как узнать, выводить ли в этом разделе рубрику А (она будет ссылкой на страницу со своими подрубриками). Разумеется, пример можно сильно усложнить (на практике именно так и произойдет).
Здравствуйте, azalt, Вы писали:
A>Какие будут мысли, коллеги?
Ну, есть много решений, которые позволяют одним запросом выбрать все поддерево. Сджойнить его со списком статей данного типа уже задача более тривиальная.
Для данного случая лучше всего подойдет транзитивное замыкание.
Ты добавляешь таблицу предок/потомок к таблице рубрик. В нее вносятся не только parent/child отношения, но и отношения grandparent/grandchild. В итоге по заданной рубрике ты можешь получить всех ее предков. Содержимое этой таблицы нужно обновлять синхронно с изменениями рубрик.
Поищи в этом форуме по словам "транзитивное замыкание" для подробностей.
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
A>>Какие будут мысли, коллеги? S>Ну, есть много решений, которые позволяют одним запросом выбрать все поддерево. Сджойнить его со списком статей данного типа уже задача более тривиальная.
Или другой ваиант — вводить уровень вложенности и корневой элемент для рубрик, т.е. рубрика знает :
1) свой уровень
2) код главного владельца
рубрика 1 (root -1) (level 1)
рубрика 1.1 (root рубрика 1) (level 2)
рубрика 1.2 (root рубрика 1) (level 2)
статья 1 Раздел 1
статья 2 Раздел 2
рубрика 2
рубрика 2.1
статья 3 Раздел 1
рубрика 2.2
статья 1 Раздел 1
таким образом при входже в раздел последовательность будет такая:
1) выбрать все корневые элементы из рубрикатора у которых код равен коду корневого улемента
у рубрик, которые содержат статьи текущего раздела
— имеем корни, текущий раздел, коды статей
далее будем иметь : текущую рубрику и ее уровень соотвественно.
2) далее вложенно, упорядочивая и группируя
по порядку корня, по уровню вложенности ,
select root_id , id , name , level from rubric
where level = 0 and id in (....)
group by root_id, id , name , level
order by name
пройти по всем коревыем элементам -> есть статья -> вывести
есть дети (select дополнительный или функция в вышестоящем запросе) — сделать ссылкой
вообще конечно лучше делать провежуточный xml, например, что бы с реляционной структурой не морочаться при выводею.
Веру-ю-у! В авиацию, в научную революци-ю-у, в механизацию сельского хозяйства, в космос и невесомость! Веру-ю-у! Ибо это объективно-о! (Шукшин)
Здравствуйте, dad, Вы писали:
dad>вообще конечно лучше делать провежуточный xml, например, что бы с реляционной структурой не морочаться при выводею.
Кстати, вот это — весьма неплохая идея. Если соотношение частот добавления статей к запросам оглавления много меньше единицы (а это обычно так и есть), то старых добрый XML великолепно это дело обработает. Особенно если кэшировать результат XSLT преобразования, которое фильтрует рубрики, и перегенерить его только при смене нижележащего XML, это будет вообще летать со страшной силой, практически независимо от количества статей. Это именно та задача, для которой RDBMS не очень хорошо подходят.
... << RSDN@Home 1.1.0 stable >>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.