MySQL иерархическое хранилище: поиск по всем родителям / бабушкам / дедушкам / и т.д. узлы с заданным идентификатором дочернего узла? - PullRequest
3 голосов
/ 22 апреля 2011

Я храню категории, используя иерархическую модель, например:

CATEGORIES
id | parent_id | name
---------------------
1  | 0         | Cars
2  | 0         | Planes
3  | 1         | Hatchbacks
4  | 1         | Convertibles
5  | 2         | Jets
6  | 3         | Peugeot
7  | 3         | BMW
8  | 6         | 206
9  | 6         | 306

Затем я сохраняю фактические данные с одним из этих идентификаторов категории, например:

CARS
vehicle_id | category_id | name
-------------------------------
1          | 8           | Really fast silver Peugeot 206 
2          | 9           | Really fast silver Peugeot 306 
3          | 5           | Really fast Boeing 747
4          | 3           | Another Peugeot but only in Hatchbacks category

При поиске любых этих данных я бы хотел найти все узлы ребенок / внук / правнук и т. Д. И т. Д. Поэтому, если кто-то хочет увидеть все «Автомобили», он видит все с parent_id «Хэтчбэков» и так далее с parent_id «Peugeot» и так далее, на произвольном уровне.

Так что, если я перечислю «действительно быстрый Peugeot 206» с category_id 1, 3, 6 или 8, мой запрос должен иметь возможность «перемещаться» вверх по дереву и находить любые более высокие категории, которые являются родителями / бабушками и дедушками этой детской категории. Например. пользователь, выполняющий поиск Peugeot в категории «8», должен найти Peugeot, перечисленных в категориях 6, 3 или 1 - все из которых являются потомками категории 8.

например. используя приведенные выше данные, при поиске «Peugeot» в категории 3 на самом деле должны быть найдены транспортные средства 1, 2 и 4, поскольку транспортные средства 1 и 2 имеют след предков категории, который ведет обратно к категории 3. См.?

Извините, если я не объяснил это хорошо. Это трудно! Спасибо, однако.

Примечание: я прочитал статью разработчиков MySQL об иерархиях .

Ответы [ 4 ]

1 голос
/ 22 апреля 2011

Нормализованные модели хороши, но не тогда, когда вам действительно нужно их запросить.

Просто сохраните «путь» к вашей категории в таблице категорий.Например: path = / 1/3/4, и при запросе к вашей базе данных, например, «выберите .... где путь похож на '/ 1/3 /%'», это будет намного проще и быстрее, чем несколько иерархических запросов ...

0 голосов
/ 26 апреля 2011

Вы представили свои данные в виде модели списка смежности, чьи запросы в MySQL лучше всего выполнять с использованием переменных сеанса . Теперь, это не единственный способ , вы можете представить иерархию в реляционной базе данных . Для вашей конкретной проблемы я бы, вероятно, вместо этого использовал бы подход материализованный путь , в котором вы покончили с таблицей фактических категорий и вместо этого получили в своей таблице автомобилей столбец, который выглядит как Cars/Hatchbacks/Peugeot для каждой записи и используйте LIKE запросов. К сожалению, это будет медленно, так как количество записей растет. Теперь, если вы знаете максимальную глубину вашей иерархии (например, четыре уровня), вы можете вместо этого разбить ее на отдельные столбцы, что позволит вам воспользоваться преимуществами индексации.

0 голосов
/ 22 апреля 2011

Мне нравится объяснение, предоставленное SitePoint. Он дает вам код и объясняет теорию, стоящую за ним.

http://blogs.sitepoint.com/hierarchical-data-database/

Примечание: этот метод лучше для чтения, чем для записи. Если вы постоянно пишете в дерево, я бы использовал другой алгоритм. Этот метод оптимизирован для чтения (поиска).

0 голосов
/ 22 апреля 2011
...