【问题标题】:Design Relational Database - Use hierarchical datamodels or avoid them?设计关系数据库 - 使用分层数据模型还是避免它们?
【发布时间】:2013-05-15 12:50:04
【问题描述】:

我正在设计一个数据库,我对在关系数据库中使用分层数据模型有一些疑问。

如果我想处理类别、子类别和父类别,是否可以不在关系数据库中使用分层数据模型?换句话说,可以用关系的方式处理类别、子类别和父类别吗?

顺便说一句,我正在使用 PostgreSQL。

对不起,我的英语不好。

最好的问候,

【问题讨论】:

标签: database-design postgresql hierarchical-data


【解决方案1】:

您有几个选项来存储层次结构:

  • 邻接列表
  • 对邻接列表的递归查询
  • 路径枚举
  • 嵌套集
  • 闭包表

如果您有 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'

【讨论】:

  • +1 用于指出递归查询(现在广泛的 DBMS 都支持)
  • 很好的例子,说明如何检索层次结构和行的深度。然后可以使用深度进行拓扑排序(ORDER BY depth)。
【解决方案2】:

如果您使用的是 Postgres,您可以将层次结构存储在一个数组中作为 materialized path

您还可以从使用这种方法的 GIN 索引中受益,在我的实验中,这种方法比递归查询具有更好的性能。

【讨论】:

【解决方案3】:

“分层数据模型”是什么意思?如果您只是指在关系或 SQL 数据库中对层次结构建模,那么这是一件非常常见且合理的事情。有大量关于如何对层次结构进行关系建模的数据库文献。这样做没有任何“非关系性”。

然而,分层数据模型这个词更多地是指一种DBMS(不是RDBMS或SQL DBMS)。分层/网络/图形 DBMS 的运行原理与 RDBMS 不同——它们使用导航或基于指针的模型,而不是关系模型。关系/SQL 模型在很大程度上(但不完全)取代了那种类型的 DBMS。除非您碰巧使用的是分层类型的 DBMS,否则您无需担心。

【讨论】:

    猜你喜欢
    • 2012-09-23
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    相关资源
    最近更新 更多