У вас есть несколько вариантов хранения иерархий:
- Список смежности
- Рекурсивный запрос в списке соседей
- Перечисление пути
- Вложенные множества
- Закрытие стола
Если у вас PostgreSQL версии 8.4 или новее, вы можете использовать рекурсивные запросы , чтобы упростить задачу. Это, безусловно, самое простое решение, легко запрашивать, легко вставлять новые записи, легко обновлять текущие записи, легко удалять записи, и у вас есть ссылочная целостность. У всех других решений есть детали, которые трудно решить.
Список приставок:
CREATE TABLE categories (
id SERIAL PRIMARY KEY,
parent_id BIGINT,
category TEXT NOT NULL,
FOREIGN KEY (parent_id) REFERENCES categories(id)
);
INSERT INTO categories(parent_id, category) VALUES(NULL, 'vehicles');
INSERT INTO categories(parent_id, category) VALUES(1, 'cars');
INSERT INTO categories(parent_id, category) VALUES(1, 'motorcycles');
INSERT INTO categories(parent_id, category) VALUES(2, 'SUV');
INSERT INTO categories(parent_id, category) VALUES(2, 'sport');
INSERT INTO categories(parent_id, category) VALUES(3, 'cruising');
INSERT INTO categories(parent_id, category) VALUES(3, 'sport');
WITH RECURSIVE tree (id, parent_id, category, category_tree, depth)
AS (
SELECT
id,
parent_id,
category,
category AS category_tree,
0 AS depth
FROM categories
WHERE parent_id IS NULL
UNION ALL
SELECT
c.id,
c.parent_id,
c.category,
tree.category_tree || '/' || c.category AS category_tree,
depth+1 AS depth
FROM tree
JOIN categories c ON (tree.id = c.parent_id)
)
SELECT * FROM tree ORDER BY category_tree;
Результат:
'1', '', 'автомобиль', 'автомобиль', '0'
'2', '1', 'авто', 'автомобиль / автомобили', '1'
4 ', '2', 'внедорожник', 'автомобиль / автомобили / SUV', '2'
'5', '2', 'Спорт', 'автомобиль / автомобили / спорт', '2'
* +1032 * '3', '1', 'мотоциклов', 'транспортное средство / мотоциклы', '1'
* +1034 * '6', '3', 'крейсерской', 'транспортного средства / мотоциклы / крейсерская', '2' * * тысяча тридцать-пять
'7', '3', 'спорт', 'транспортное средство / мотоциклы / спорт', '2' * * тысяча тридцать семь