您有几个选项来存储层次结构:
- 邻接列表
- 对邻接列表的递归查询
- 路径枚举
- 嵌套集
- 闭包表
如果您有 PostgreSQL 版本 8.4 或更高版本,您可以使用recusive queries 让事情变得非常简单。这是迄今为止最简单的解决方案,易于查询、易于插入新记录、易于更新当前记录、易于删除记录并且具有参照完整性。所有其他解决方案都有难以解决的部分。
邻接列表:
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','cars','vehicle/cars','1'
'4','2','SUV','车辆/汽车/SUV','2'
'5','2','sport','vehicle/cars/sport','2'
'3','1','摩托车','车辆/摩托车','1'
'6','3','巡航','车辆/摩托车/巡航','2'
'7','3','运动','车辆/摩托车/运动','2'