设计关系数据库 - 使用分层数据模型还是避免使用它们?

发布于 2024-10-15 18:47:19 字数 177 浏览 6 评论 0原文

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

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

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

抱歉我的英语不好。

此致,

I'm designing a Database and I have some doubts on using Hierarchical datamodels in relational databases.

If I want to deal with categories, subcategories and parent categories it is possible not to use a Hierarchical datamodels in a relational database? By another words, it is possible to deal with categories, subcategories and parent categories using the relational way of doing things?

By the way, I'm using PostgreSQL.

Sorry for my bad english.

Best Regards,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

嘿看小鸭子会跑 2024-10-22 18:47:19

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

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

如果您有 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','车辆/汽车/SUV','2'

“5”、“2”、“运动”、“车辆/汽车/运动”、“2”

'3','1','摩托车','车辆/摩托车','1'

'6','3','巡航','车辆/摩托车/巡航','2'

'7','3','运动','车辆/摩托车/运动','2'

You have a couple of options to store hierachies:

  • Adjacency List
  • Recursive Query on a adjancy list
  • Path Enumeration
  • Nested Sets
  • Closure Table

If you have PostgreSQL version 8.4 or later, you can use recusive queries to make things very easy. This is by far the easiest solution, easy to query, easy to insert new records, easy to update current records, easy to delete records and you have referential integrity. All other solutions have parts that are hard to solve.

Adjency list:

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;

Result:

'1','','vehicle','vehicle','0'

'2','1','cars','vehicle/cars','1'

'4','2','SUV','vehicle/cars/SUV','2'

'5','2','sport','vehicle/cars/sport','2'

'3','1','motorcycles','vehicle/motorcycles','1'

'6','3','cruising','vehicle/motorcycles/cruising','2'

'7','3','sport','vehicle/motorcycles/sport','2'

不交电费瞎发啥光 2024-10-22 18:47:19

如果您使用 Postgres,则可以将层次结构作为具体化路径存储在数组中。

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

If you're using Postgres, you can store the hierarchy in an array as a materialized path.

You also benefit from GIN indexing with this approach, which in my experiments has had better performance than a recursive query.

月寒剑心 2024-10-22 18:47:19

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

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

What do you mean by "hierarchical data model"? If you just mean modelling a hierarchy in a relational or SQL database then that's a perfectly common and reasonable thing to do. There is a significant quantity of database literature on the subject of how to model hierarchies relationally. There is nothing "non relational" about doing that.

However, the term Hierarchical Data Model more usually refers to a type of DBMS (not an RDBMS or SQL DBMS). Hierarchical / Network / Graph DBMSs operate on different principles to RDBMSs - they use navigational or pointer-based models rather than the relational model. The relational / SQL model has largely (but not entirely) superseded that type of DBMS. Unless you happen to be using a hierarchical type of DBMS then you don't need to worry about it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文