公司要做一个树状结构,列表展示的时候不仅要有节点信息,还要有该节点的路径信息。
众所周知mysql没有oracle 的递归查询,如果Java代码中查询的话。列表页几十条数据。在每个节点层数不定时,其实时间都花费在数据库的连接上。
又不想mysql增加自定义函数(个人觉得不利于数据迁移)。所以学习了一下前人的树状结构表设计。
首先解决拿来主义
将第一套理论和第二套理论整合到一起。既可以解决效率问题,也可以满足常用的需求,当树状结构进行管理时。关联树状结构的信息只需要保存节点id就可以了。
树状结构变更时,tree_path的parent_id 都需要维护。
CREATE TABLE `event_link_tree` (
`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '节点ID',
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '节点名称',
`paernt_id` bigint(11) NOT NULL DEFAULT '0' COMMENT '父节点ID',
`tree_path` varchar(255) NOT NULL DEFAULT '' COMMENT '节点路径信息例如/1/2/3/',
`creater` varchar(255) NOT NULL DEFAULT '' COMMENT '创建者',
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_by` varchar(255) NOT NULL DEFAULT '' COMMENT '修改者',
`update_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
`remark` varchar(255) NOT NULL DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
方案一(Adjacency List)
CREATE TABLE tree(
node_id int,
node_name varchar2(100),
parent_id int
);
这种结构应该是目前最常用的。
优点:1 便于直接查询已知节点的上下级节点。
2 增删改查比较便捷
缺点:无法一次查询得到层级关系。
方案二(Path Enumeration)
CREATE TABLE tree_Path(
node_id int,
node_name varchar2(100),
path varchar2(1000)
);
例子
优点:
1 解决了第一种方案的缺点无法查询路径的问题
2 而且可以通过以下的方法查询节点的父节点和子节点。
select id ,name,tree_path from event_link_tree where tree_path like '/1/2/%'
select id ,name,tree_path from event_link_tree where tree_path like '%/2/%'
另外两种,因为不符合自己的场景,所以不做细致说明,参考大牛文章,链接如下