我有一个使用Closure Table方法保存分层数据的MySQL数据库.一个简单的示例数据库创建脚本遵循该问题.我目前的问题是如何以正确的顺序从数据库中提取数据?我目前正在使用以下select语句.
SELECT `TreeData`.`iD`, `TreeData`.`subsectionOf`,
CONCAT(REPEAT('-', `TreePaths`.`len`),`TreeData`.`name`),
`TreePaths`.`len`,`TreePaths`.`ancestor`,`TreePaths`.`descendant`
FROM `TreeData`
LEFT JOIN `TreePaths` ON `TreeData`.`iD` = `TreePaths`.`descendant`
WHERE `TreePaths`.`ancestor` = 1
ORDER BY `TreeData`.`subsectionOrder`
Run Code Online (Sandbox Code Playgroud)
它会提取正确的信息,但输入顺序不正确.
示例数据库使用示例数据创建脚本.
-- Simple Sample
SET FOREIGN_KEY_CHECKS=0;
DROP TRIGGER IF EXISTS Tree_Insert;
DROP TRIGGER IF EXISTS Tree_Update;
DROP TABLE IF EXISTS TreePaths;
DROP TABLE IF EXISTS TreeData;
SET FOREIGN_KEY_CHECKS=1;
CREATE TABLE `TreeData` (
`iD` INT NOT NULL, -- PK
`subsectionOf` INT, -- Parent ID & FK
`subsectionOrder` INT, -- Oder of Subsections
`name` NVARCHAR(500) NOT NULL, …Run Code Online (Sandbox Code Playgroud) 我在SQL Server数据库中使用了一组分层数据.数据以guid作为主键存储,而parentGuid作为指向直接父对象的外键存储.我最常通过WebApi项目中的Entity Framework访问数据.为了使情况更复杂,我还需要基于此层次结构管理权限,以便应用于父级的权限适用于其所有后代.我的问题是:
我已经搜遍了所有,无法决定哪种方法最适合处理这种情况.我知道我有以下选择.
Recursive CTEsCommon Table Expression(也就是RCTE)来处理分层数据.这似乎是正常访问最简单的方法,但我担心在用于确定子对象的权限级别时可能会很慢.hierarchyId表中,并使用SQL Server所提供的功能,如数据类型字段GetAncestor(),IsDescendantOf()和等,这似乎将让查询很容易,但似乎需要一个相当复杂的插入/更新触发器,以保持HIERARCHYID域是正确的通过插入和移动closure table,它将存储表中的所有关系.我想象如下:父列和子列,每个父 - >子关系将被表示.(即1-> 2 2-> 3将在数据库中表示为1-2,1-3,2-3).缺点是这需要插入,更新和删除触发器,即使它们非常简单,并且此方法会生成大量记录.我已经尝试过全面搜索,但在这三种方法之间找不到任何建议.
PS我也对这个问题的任何替代解决方案持开放态度
sql-server recursive-query common-table-expression hierarchyid transitive-closure-table
我使用PostgreSQL 9.1来查询分层树结构数据,包括与节点连接的边(或元素).数据实际上是用于流网络,但我已经将问题抽象为简单的数据类型.考虑示例tree表.每条边都有长度和面积属性,用于确定网络中的一些有用指标.
CREATE TEMP TABLE tree (
edge text PRIMARY KEY,
from_node integer UNIQUE NOT NULL, -- can also act as PK
to_node integer REFERENCES tree (from_node),
mode character varying(5), -- redundant, but illustrative
length numeric NOT NULL,
area numeric NOT NULL,
fwd_path text[], -- optional ordered sequence, useful for debugging
fwd_search_depth integer,
fwd_length numeric,
rev_path text[], -- optional unordered set, useful for debugging
rev_search_depth integer,
rev_length numeric,
rev_area numeric
);
CREATE INDEX ON tree (to_node);
INSERT INTO …Run Code Online (Sandbox Code Playgroud) postgresql recursive-query common-table-expression hierarchical-query transitive-closure-table
我想请你帮我解决存储为闭包表的分层数据结构的问题.
我想用这个结构来存储我的网站菜单.一切正常,但问题是我不知道如何按自定义顺序对确切的子树进行排序.目前,树按照项目添加到数据库的顺序排序.
我的结构基于Bill Karwin关于Closure Tables 的文章以及其他一些帖子.
这是我的MySQL数据库结构,包含一些DEMO数据:
--
-- Table `category`
--
CREATE TABLE IF NOT EXISTS `category` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) COLLATE utf8_czech_ci NOT NULL,
`active` tinyint(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `category` (`id`, `name`, `active`) VALUES
(1, 'Cat 1', 1),
(2, 'Cat 2', 1),
(3, 'Cat 1.1', 1),
(4, 'Cat 1.1.1', 1),
(5, 'Cat 2.1', 1),
(6, 'Cat 1.2', 1),
(7, …Run Code Online (Sandbox Code Playgroud) 我的关系数据库(Firebird)中有一个DAG,有两个表edge和node(邻接列表模型).我想以递归方式查询它们,但发现递归查询非常低效.因此,我试图在Dong et.al之后实现触发器以维持传递闭包.论文http://homepages.inf.ed.ac.uk/libkin/papers/tc-sql.pdf.
SELECTs现在非常快,但是DELETEs非常慢,因为几乎整个图形被复制用于单个删除.更糟糕的是,并发更新似乎不可能.
有没有更好的方法来实现这个?
编辑
我做了一些实验并向TC表引入了一个参考计数器.有了这个,删除很快.我写了一些简单的测试用例,但我不确定我做得对.这是我到目前为止:
CREATE GENERATOR graph_tc_seq;
CREATE TABLE EDGE (
parent DECIMAL(10, 0) NOT NULL,
child DECIMAL(10, 0) NOT NULL,
PRIMARY KEY (parent, child)
);
CREATE TABLE GRAPH_TC (
parent DECIMAL(10, 0) NOT NULL,
child DECIMAL(10, 0) NOT NULL,
refcount DECIMAL(9, 0),
PRIMARY KEY (parent, child)
);
CREATE TABLE GRAPH_TC_TEMP (
session_id DECIMAL(9, 0),
parent DECIMAL(10, 0),
child DECIMAL(10, 0)
);
CREATE PROCEDURE GRAPH_TC_CREATE (p_parent DECIMAL(10, 0), c_child …Run Code Online (Sandbox Code Playgroud) sql firebird directed-acyclic-graphs transitive-closure-table
我正在开始一个有一些分层数据的新项目,我正在查看目前存储在数据库中的所有选项.
我正在使用PostgreSQL,它允许递归查询.我还研究了关系数据库的设计模式,比如闭包表,我看了一下图形数据库解决方案,比如neo4j.
我发现很难在这些选项之间做出决定.例如:假设我的RDBMS允许递归查询,那么使用闭包表是否仍然有意义?在可维护性和性能方面,它与图数据库解决方案相比如何?
任何意见/经验将不胜感激!
postgresql rdbms hierarchical-data neo4j transitive-closure-table
我有一个数据库,其中包含使用邻接列表模型存储的类别层次结构.
层次结构深度为3级(不包括假想的根节点),包含大约1700个节点.第二级和第三级的节点可以有多个父节点.另外一个表用于多对多关系,如下所示:
CREATE TABLE dbo.Category(
id int IDENTITY(1,1) NOT NULL,
name varchar(255) NOT NULL,
)
CREATE TABLE dbo.CategoryHierarchy(
relId int IDENTITY(1,1) NOT NULL,
catId int NOT NULL,
parentId int NOT NULL,
)
Run Code Online (Sandbox Code Playgroud)
如果我转向使用传递闭包表方法(为了数据完整性等)是否有一个相对容易的查询,我可以执行,将生成闭包表的值?(使用SQL Server 2005)
我查看文章和演示文稿,例如Bill Karwin的分层数据模型,但只有单个节点的插入查询,我需要永远创建这样的树.
谢谢.
编辑:
CategoryHierarchy表中的RelID纯粹是为了主键,它与Category表的节点ID无关.
还有闭包表,我的意思是这样一个表:
CREATE TABLE ClosureTable (
ancestor int NOT NULL,
descendant int NOT NULL,
[length] int NOT NULL,
)
Run Code Online (Sandbox Code Playgroud)
前两列是复合主键,并且是Category.id的单独外键.
注意:在RhodiumToad的#postgresql帮助下,我已经找到了一个解决方案,我将其作为答案发布.如果有人可以改进这一点,请加入!
我无法使先前的递归查询解决方案适应包含多个"根"(无祖先)节点的以下有向非循环图.我正在尝试编写一个查询,其输出通常称为闭包表:一个多对多表,它存储从每个节点到每个后代及其自身的每条路径:
1 2 11 8 4 5 7
\/ | | \ | /
3 | \ 6
\ | \ /
9 | 10
\/ /
12 13
\ /
14
CREATE TABLE node (
id SERIAL PRIMARY KEY,
node_name VARCHAR(50) NOT NULL
);
CREATE TABLE node_relations (
id SERIAL PRIMARY KEY,
ancestor_node_id INT REFERENCES node(id),
descendant_node_id INT REFERENCES node(id)
);
INSERT into node (node_name)
SELECT 'node ' || g FROM generate_series(1,14) g;
INSERT INTO node_relations(ancestor_node_id, …Run Code Online (Sandbox Code Playgroud) 我创建了一个简单的例子来说明PostgreSQL中使用递归查询的传递闭包.
但是,我的递归查询有些问题.我不熟悉语法,所以这个请求可能完全是我的noobish,为此我提前道歉.如果运行查询,您将看到节点1在路径结果中重复自身.有人可以帮我弄清楚如何调整SQL吗?
/* 1
/ \
2 3
/ \ /
4 5 6
/
7
/ \
8 9
*/
create table account(
acct_id INT,
parent_id INT REFERENCES account(acct_id),
acct_name VARCHAR(100),
PRIMARY KEY(acct_id)
);
insert into account (acct_id, parent_id, acct_name) values (1,1,'account 1');
insert into account (acct_id, parent_id, acct_name) values (2,1,'account 2');
insert into account (acct_id, parent_id, acct_name) values (3,1,'account 3');
insert into account (acct_id, parent_id, acct_name) values (4,2,'account 4');
insert into account (acct_id, parent_id, acct_name) values (5,2,'account 5'); …Run Code Online (Sandbox Code Playgroud) sql postgresql recursive-query common-table-expression transitive-closure-table
我想实现分层数据结构(例如Product - > Product 2 ----> Product3,Product 2 ----> Product4)使用实体框架6代码的第一种方法.有几种方法可用,但我认为封闭表方法可以满足我的所有要求.有人可以指导我如何有效地或任何其他替代方案在实体框架6中实施闭包表方法?
postgresql ×4
sql ×4
mysql ×2
sql-server ×2
firebird ×1
hierarchical ×1
hierarchy ×1
hierarchyid ×1
neo4j ×1
rdbms ×1