2010-08-02 3 views
3

Постараюсь выставить как можно более ясно;)DB Design: лучшие практики в иерархическую структуру

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

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

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 "ALL SONS OF Bar" 

выход:

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

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

Любая идея?

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

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

В качестве примечания, используя внешние ключи (или аналогичное поведение) будет лучше (удаление одного «отца» следует удалить все Чайлдс - нет детей-сирот не допускается)

+0

Как часто будут изменяться данные и как они будут меняться (добавьте листы, обменивайте ветви, удалите узлы из середины/свяжитесь с сиротами и т. Д. И т. Д.). Упрощенные системы могут содержать ярлыки, но если вам нужна серьезная гибкость, все может стать сложным. –

+1

Значение 0 неверно, нет значения entry_id с этим значением: любое ограничение внешнего ключа завершится с ошибкой. Используйте NULL, если у вас нет родителя. –

+0

@frank: вы правы. – Strae

ответ

10

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

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

+1

+1 для функции WITH RECURSIVE. – rfusca

4

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

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

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

+1

Если вы смотрите слайд-шоу, обратите особое внимание на модель вложенного набора. Также обратите внимание, что список смежности - это ваш дизайн. –

Смежные вопросы