• 豫都门户网
  • 您的位置:首页 >> 国内新闻 >> 正文

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

    发表时间:2019-09-14 信息来源:www.st2888.cn 浏览次数:1971

     

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

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

    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来表示深度,它只是一个简单的查询操作。

    http://www.sugys.com/bdsiVhZmG

  • 热门标签

  • 日期归档

  • 友情链接:

    豫都门户网 版权所有© www.st2888.cn 技术支持:豫都门户网 | 网站地图