您的位置:首页 > 国内新闻

mysql 开发技巧(一):这才是正确存储树形结构数据的方式

时间:2019-09-18

有时我们的应用程序将保存一些树形数据结构,如论坛回复,公司组织结构,产品分类,知识库和其他相关的树结构。这些数据之间存在递归关系,那么我们今天如何走?存储树结构?

普通开发人员将设计一个这样的表结构,每个记录存储前一个记录的父节点,这可能是这样的表结构:

CREATE TABLE`t_comment`(

`cmmonent_id` int(11)NOT NULL AUTO_INCREMENT,

`parent_id` int(11)DEFAULT NULL,

`comments`文字,

PRIMARY KEY(`cmmonent_id`)

)ENGINE=InnoDB DEFAULT CHARSET=utf8;

实际数据可能如下所示:

如果有这样一个表结构,当讨论很多内容的话题时,需要编写更复杂的代码来进行许多记录的递归检索,查询的效率会非常低。相反,如果数据量不大,讨论内容相对固定,数据层数量少,那么这个方案相对简单,在这种情况下,结构仍然符合需求。但是无法保证帖子不能成为热帖,因此重启服务器可能需要一晚的时间。

在这里,我们讨论两个更通用,更广泛的解决方案:路径枚举和闭包表。

对于上表(t_comment)结构,我们可以添加一个字段路径来记录节点的所有父信息。记录的方法是将所有父信息组织称为字符串。类似于下表的形式:

由于路径路径存储节点的所有父节点信息,因此我们可以轻松获取节点的所有父节点。例如,我们可以使用该程序首先获取路径的值字符串,然后使用该字符串。 split函数处理所有父节点。

如果要查询节点的所有后代,例如查找comment_id等于3的所有后代,可以使用以下查询:

从评论中选择*,其路径如'1/2/3 _%';

如果要查询下一层的子节点,可以使用以下查询:

SELECT * from t_comment其中path regexp'1/2/3/[0-9] $';

要插入操作,请首先复制父节点的路径以及新comment_id的值。路径枚举使查询子节点和父节点更容易。通过查看分隔符的数量,您可以了解节点层次结构。虽然添加字段来存储数据,但应用程序需要添加其他代码验证路径信息。正确性,但这种设计更加广泛,更适应未来日益增长的数据。 parent_id列仍然在此设计中保留,这对于某些操作更方便,并且还可用于验证路径信息的正确性。

闭包表也是一种通用的解决方案,它需要一个额外的表来记录节点的关系。它的节点关系不仅包括父子同时记录所有节点之间的关系。它可以很容易地理解为多对多关系中的中间表。它只是一个闭包结构,它与自己联系在一起。

例如,表结构:

创建表t_path(

Parent_id int(11)not null,

Sub_id int(11)not null,

主键(parent_id,sun_id)

实际数据可能如下所示:

使用此关系表,可以非常轻松地找到子节点和父节点,这相当于单个表操作。例如,统计节点3的所有子节点都可以查询关系表t_path;

从t_path中选择count(1),其中parent_id=3,sub_id 3;

无论是新字段还是存储节点关系的新表,它都是典型的时空解决方案。相比之下,关闭表之间的关系更容易维护,即简单的单表添加,删除和更改。操作。计算父节点的数量是深度,如果不想要额外的计数,可以添加一个字段path_length来表示深度,它只是一个简单的查询操作。

——

  • 友情链接:
  • 康乐信息网 版权所有© www.lojasnipon.com 技术支持:康乐信息网| 网站地图