推荐两种MySQL无限级分类设计方案

推荐两种MySQL无限级分类设计方案

首页休闲益智2048分类更新时间:2024-05-13

软件开发过程中我们经常会遇到各种各样多级的数据结构需求。刚开始与产品沟通的最多只支持3级。后期根据需求的迭代3级变成多级再变成无限级。有时候产品为了减少麻烦产品初级就会定义支持无限的分类结构。分类的产品需求非常简单可能就一句话支持无限级的分类数据结构。但分类的代码开发繁琐麻烦有时候还有点复杂。

今天为大家介绍两种无限级分类设计方案。大家可以根据自身的业务需求合理使用解决方案。

第一种方案:父ID方式

1、表结构设计

CREATE TABLE IF NOT EXISTS `classify`( `class_id` INT UNSIGNED AUTO_INCREMENT COMMENT '自增分类id', `class_name` VARCHAR(128) NOT NULL COMMENT '分类名称', `type` SMALLINT(1) NOT NULL DEFAULT 1 COMMENT '分类类型', `parent_id` INT UNSIGNED NOT NULL DEFAULT 0 COMMENT '分类父级id', `status` SMALLINT(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '1 正常 2 删除', `create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '更新时间', `ext_data` VARCHAR(1024) NOT NULL DEFAULT '[]' COMMENT '扩展信息json', PRIMARY KEY ( `class_id` ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT '综合业务分类表'; #批量插入测试数据 INSERT INTO classify(`class_id`, `class_name`, `parent_id`, `status`) values(1, 'a', 0, 1),(2,'a1',1,1),(3,'b',0,1),(4,'a11',2,1),(5,'a12',2,1)

2、代码开发

#查询所有分类数据(执行db一次) $conn = new mysqli('127.0.0.1', 'root', '', 'test'); if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } $sql = "SELECT class_id, class_name, parent_id FROM classify WHERE `type` = 1"; $result = $conn->query($sql); $arrList = array(); while($row = $result->fetch_assoc()) { $arrList[] = $row; } #递归函数组合分类数据结构 function build_classify_tree($arrList,$intClassId) { $arrTree = array(); foreach($arrList as $arrItem) { if($arrItem['parent_id'] == $intClassId) { $arrItem['child'] = build_classify_tree($arrList, $arrItem['class_id']); $arrTree[] = $arrItem; } } return $arrTree; } $arrTree = build_classify_tree($arrList, 0); $conn->close();

3、执行结果

array(2) { [0]=> array(4) { ["class_id"]=> string(1) "1" ["class_name"]=> string(1) "a" ["parent_id"]=> string(1) "0" ["child"]=> array(1) { [0]=> array(4) { ["class_id"]=> string(1) "2" ["class_name"]=> string(2) "a1" ["parent_id"]=> string(1) "1" ["child"]=> array(2) { [0]=> array(4) { ["class_id"]=> string(1) "4" ["class_name"]=> string(3) "a11" ["parent_id"]=> string(1) "2" ["child"]=> array(0) { } } [1]=> array(4) { ["class_id"]=> string(1) "5" ["class_name"]=> string(3) "a12" ["parent_id"]=> string(1) "2" ["child"]=> array(0) { } } } } } } [1]=> array(4) { ["class_id"]=> string(1) "3" ["class_name"]=> string(1) "b" ["parent_id"]=> string(1) "0" ["child"]=> array(0) { } } }

第二种方案:父路径方式

1、表结构设计

CREATE TABLE IF NOT EXISTS `category`( `class_id` INT UNSIGNED AUTO_INCREMENT COMMENT '自增分类id', `class_name` VARCHAR(128) NOT NULL COMMENT '分类名称', `type` SMALLINT(1) NOT NULL DEFAULT 1 COMMENT '分类类型', `parent_path` VARCHAR(2048) NOT NULL DEFAULT '' COMMENT '分类父级路径', `status` SMALLINT(1) UNSIGNED NOT NULL DEFAULT 1 COMMENT '1 正常 2 删除', `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` DATETIME NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '更新时间', `ext_data` VARCHAR(1024) NOT NULL DEFAULT '[]' COMMENT '扩展信息json', PRIMARY KEY ( `class_id` ) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; #批量插入测试数据 INSERT INTO category(`class_id`, `class_name`, `parent_path`, `status`) values(1, 'a', '/', 1),(2,'a1','/a/',1),(3,'b','/',1),(4,'a11','/a/a1/',1),(5,'a12', '/a/a1/', 1)

2、代码设计

$conn = new mysqli('127.0.0.1', 'root', '', 'test'); if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } $sql = "SELECT class_id, class_name, parent_path FROM category WHERE `type` = 1"; $result = $conn->query($sql); $arrList = array(); while($row = $result->fetch_assoc()) { $arrList[] = $row; } function build_classify_tree($arrList,$strParentPath) { $arrTree = array(); foreach($arrList as $arrItem) { if($arrItem['parent_path'] == $strParentPath) { $strChildParentPath = sprintf('%s%s', $strParentPath, $arrItem['class_name'] . '/'); $arrItem['child'] = build_classify_tree($arrList, $strChildParentPath); $arrTree[] = $arrItem; } } return $arrTree; } $arrTree = build_classify_tree($arrList, '/'); var_dump($arrTree); $conn->close();

3、执行结果

array(2) { [0]=> array(4) { ["class_id"]=> string(1) "1" ["class_name"]=> string(1) "a" ["parent_path"]=> string(1) "/" ["child"]=> array(1) { [0]=> array(4) { ["class_id"]=> string(1) "2" ["class_name"]=> string(2) "a1" ["parent_path"]=> string(3) "/a/" ["child"]=> array(2) { [0]=> array(4) { ["class_id"]=> string(1) "4" ["class_name"]=> string(3) "a11" ["parent_path"]=> string(6) "/a/a1/" ["child"]=> NULL } [1]=> array(4) { ["class_id"]=> string(1) "5" ["class_name"]=> string(3) "a12" ["parent_path"]=> string(6) "/a/a1/" ["child"]=> NULL } } } } } [1]=> array(4) { ["class_id"]=> string(1) "3" ["class_name"]=> string(1) "b" ["parent_path"]=> string(1) "/" ["child"]=> NULL } }

大家倾向于哪种方案呢?我个人比较喜欢第二种方案因为分类结构在表里一眼就可以看出来。

感谢大家的评论、点赞、分享、关注。。。

,
大家还看了
也许喜欢
更多游戏

Copyright © 2024 妖气游戏网 www.17u1u.com All Rights Reserved