БД Дизайн: лучшие практики для иерархической структуры - PullRequest
4 голосов
/ 02 августа 2010

Я постараюсь выставить как можно яснее;)

Что ж, мне нужно хранить некоторые данные, которые могут быть связаны между собой как родительские> дочерние отношения с безлимитной глубиной.

Моя первая попытка была:

entry_id | parent_id | value
    1    |   NULL    | Foo //foo is the grand parent
    2    |    1      | Bar //bar is child of Foo
    3    |    1      | Baz //baz too
    4    |    2      | Bho //bho is child of Bar
    5    |    4      | Som //som is child of Bho
    6    |   NULL    | Git //another grand parent
    7    |    6      | Tim //Git's child

.. и т. Д.

Эта структура работает, но ее невозможно (или, по крайней мере, я не смог бы пройти через нее) найти все дочерние элементы Foo и «дочерние элементы» с помощью всего одного запроса ... для этого нужен цикл.

Моя цель состоит в том, чтобы оптимизировать структуру для запроса SELECT, которая может дать мне все взаимосвязи за один раз, что-то вроде:

 SELECT "ALL SONS OF Bar"

выход:

  entry_id | parent_id | value
     1     |   NULL    |  Bar
     4     |    2      |  Bho
     5     |    4      |  Som

но эта структура, похоже, не позволяет мне сделать это.

Есть идеи?

Если может иметь значение, я буду работать на Postgresql (я думал, что использовать тип полей массива, но запрос не будет очень быстро)

Редактировать для комментария Филиппа: в моем конкретном случае данные не должны меняться слишком часто, но мне, вероятно, придется использовать эту структуру для других аналогичных задач - но не равных - где данные обновляется много раз.

В качестве дополнительного примечания лучше всего использовать внешние ключи (или аналогичное поведение) (удаление одного «отца» должно привести к удалению всех дочерних элементов - дети-сироты не допускаются)

Ответы [ 2 ]

11 голосов
/ 02 августа 2010

Я думаю, вам будет полезно прочитать Управление иерархическими данными в MySQL .В нем рассказывается, как превратить плоский стол в иерархию с помощью пары атрибутов и некоторой служебной работы.Даже если вы не собираетесь идти по этому пути, это проницательно.

Для PostgreSQL вы можете сделать это с помощью WITH RECURSIVE запросов: WITH Queries (Common Table Expressions) .
Вам нужна как минимум версия 8.4, чтобы использовать их.

6 голосов
/ 02 августа 2010

Билл Карвин сделал хорошее слайд-шоу об иерархических данных:

http://www.slideshare.net/billkarwin/models-for-hierarchical-data

И, как уже сказал jmz, рекурсивные запросы действительно решают проблемы.

...