以最佳方式存储分层数据:NoSQL 或 SQL

问题描述 投票:0回答:3

我正在处理分层数据,如树结构。我想知道将它们存储在数据库中的最佳方式是什么。

我从 MySQL 中的邻接表开始。但随着数据的增加,性能似乎会下降。我有大约 20,000 行存储在具有父子关系的 MySQL 表中,并且将来还会增加。获取数据需要很长时间,因为我必须根据树的深度编写许多自连接。

所以我正在寻找存储此类数据的最佳方法。在一次地方,我发现嵌套集比邻接列表更好。然后我被建议考虑 NoSQL,如果这能解决我的问题。所以我现在很困惑是继续使用 SQL 还是进入 No SQL 或者是否有其他最好的方法来处理此类数据。

那么有人可以建议我什么是最好的方法吗?

mysql hierarchical-data adjacency-list nested-sets nosql
3个回答
4
投票

如果 MySQL 给您带来的麻烦多于它解决的问题,我会考虑一下 MongoDB、CouchDB 或 ElasticSearch(取决于您的用例)。甚至可能是 Neo4j。您的选择应该归结为几个要点,例如复制、扩展能力、一致性……我建议您在做出决定之前仔细阅读一些官方文档。这是用于比较的起点

采用 NoSQL 将摆脱所有连接并提高性能,但您仍然需要使用邻接列表、嵌套集、物化路径等来实现适当的层次结构......

请记住,上述 NoSQL 技术几乎都使用最终一致性,这本质上意味着您的数据在给定时间在某些节点之间可能不一致。如果这是一个问题,您应该坚持使用 RDBMS。


1
投票

Postgres 对它有原生支持,使用

ltree
:

-- Ltree type presentation
-- Farshid Ashorui

-- First of all, this is an extension (included with standard installation)
CREATE EXTENSION IF NOT EXISTS ltree;

-- We need to specify `ltree` type.
CREATE TABLE IF NOT EXISTS tree(
    id serial primary key,
    letter char,
    path ltree
);


-- we are using `gist` index for super fast indexing of the path.
-- read more here: http://patshaughnessy.net/2017/12/15/looking-inside-postgres-at-a-gist-index
-- This is Postgres’s GiST index API to find and match descendant nodes
CREATE INDEX IF NOT EXISTS tree_path_idx ON tree USING GIST (path);


-- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

-- Root of heirarchy
insert into tree (letter, path) values ('A', 'A');
insert into tree (letter, path) values ('B', 'A.B');
-- Notice here, we are deviating 
insert into tree (letter, path) values ('C', 'A.C');
insert into tree (letter, path) values ('D', 'A.C.D');
insert into tree (letter, path) values ('E', 'A.C.E');
insert into tree (letter, path) values ('F', 'A.C.F');
-- Back to B path
insert into tree (letter, path) values ('G', 'A.B.G');





-- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
-- Search for A.C path
select * from tree where path <@ 'A.C';
-- More advanced one:
select * from tree where strpos(path::varchar, 'A.B.G') = 1;

0
投票

您可以参考文章,其中讨论了处理分层数据的四种选项:

  1. 邻接列表
  2. 路径枚举
  3. 嵌套集
  4. 关闭表

邻接列表

每个条目都知道其直接父条目

路径枚举

在每个节点中存储祖先链

嵌套集

每个条目都使用左右数字对其后代进行编码

关闭表

单独的表来管理祖先和后代的映射。

© www.soinside.com 2019 - 2024. All rights reserved.