Иерархическая фильтрация в реляционной базе данных - PullRequest
3 голосов
/ 12 января 2010

В моей программе есть несколько элементов, которые принадлежат к определенной категории. Я хотел бы вернуть только те товары, которые относятся к этой категории. Проблема в том, что категории могут иметь родительские категории. Например, допустим, есть категория «Материал» с дочерней категорией «Еда» с дочерней категорией «Фрукты». У меня есть предметы: яблоко, груша, шоколад и компьютер.

Если я хочу отобразить все плоды, легко выполнить запрос к базе данных с предложением «WHERE item.category = FRUIT_ID». Однако, если я хочу, чтобы все продукты были включены, мне также нужен способ, чтобы фрукты там были.

Я знаю, что в некоторых базах данных, таких как Oracle, есть понятие рекурсивных запросов, и это может быть правильным решением, но у меня нет большого опыта работы с иерархическими данными и я ищу общие предложения. Предположим, у меня есть неограниченный контроль над схемой базы данных, дерево категорий идет максимум максимум на 5 категорий, и мне нужно, чтобы оно было смехотворно быстрым, насколько это возможно.

Ответы [ 5 ]

2 голосов
/ 12 января 2010

Посмотрите на модель списка смежности - она ​​не идеальна (очень медленно обновляется), но в некоторых ситуациях (иерархические запросы) она отлично подходит, особенно для таких проблем, как ваша.

1 голос
/ 12 января 2010

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

Затем, когда вы запрашиваете базу данных, вы просто используете предложение IN со списком дочерних идентификаторов

1 голос
/ 12 января 2010

Есть целая книга , полная стратегий проектирования для представления деревьев в SQL. Стоит взглянуть только на очевидные умные моменты.

0 голосов
/ 12 января 2010

Я думаю, что ваша схема базы данных довольно хорошо, но реализация этого поиска действительно зависит от вашей конкретной СУБД. У многих из них есть способы выполнить такую ​​рекурсию. Одним из примеров, который я могу вспомнить, является поддержка SQL Server Общих табличных выражений , которые являются молниеносной альтернативой этим неприятным курсорам.

Если вы укажете, какую СУБД вы используете, вы можете получить более конкретные ответы.

0 голосов
/ 12 января 2010

Одним из возможных решений является отделение иерархии от фактической категоризации. Например, яблоко можно отнести к категории фруктов и продуктов питания. Классификация не знает, что фрукт - это еда, но вы можете определить это где-то еще. Тогда ваш запрос будет таким же простым, как where category='food'.

В качестве альтернативы, вы можете пройти иерархию до построения запроса, и для этого потребуется что-то вроде where category='food' or category='fruit'.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...