MySQL电商多级分类表设计方案对比

news2024/11/14 12:04:11

MySQL电商多级分类表设计方案对比

在电商系统中,多级分类是一个常见的需求,用于组织和管理商品类别,合理的设计可以提高系统的性能和可维护性。本文将详细介绍三种不同的多级分类表设计方案,我们将使用宠物分类作为示例数据,并展示如何查询所有分级关系及其性能对比。

1. 需求分析

在电商系统中,宠物分类通常具有多级结构,例如:

  • 宠物用品
    • 猫用品
      • 猫粮
      • 猫玩具
    • 狗用品
      • 狗粮
      • 狗玩具

2. 设计方案

我们将介绍三种不同的多级分类表设计方案:邻接表模型、路径枚举模型和嵌套集模型。

2.1 邻接表模型(Adjacency List Model)

邻接表模型是最简单和最常见的多级分类设计方法。每个分类记录包含一个字段来表示其父级分类的 ID。

表结构
CREATE TABLE pet_categories_adjacency (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    parent_id INT DEFAULT NULL,
    sort INT NOT NULL DEFAULT 0 COMMENT '排序',
    is_show TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '是否显示',
    create_time INT NOT NULL COMMENT '创建时间',
    update_time INT NOT NULL COMMENT '更新时间'
);
插入示例数据
INSERT INTO pet_categories_adjacency (name, parent_id, sort, is_show, create_time, update_time) VALUES ('宠物用品', NULL, 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_adjacency (name, parent_id, sort, is_show, create_time, update_time) VALUES ('猫用品', 1, 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_adjacency (name, parent_id, sort, is_show, create_time, update_time) VALUES ('狗用品', 1, 2, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_adjacency (name, parent_id, sort, is_show, create_time, update_time) VALUES ('猫粮', 2, 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_adjacency (name, parent_id, sort, is_show, create_time, update_time) VALUES ('猫玩具', 2, 2, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_adjacency (name, parent_id, sort, is_show, create_time, update_time) VALUES ('狗粮', 3, 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_adjacency (name, parent_id, sort, is_show, create_time, update_time) VALUES ('狗玩具', 3, 2, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
查询所有分级关系
WITH RECURSIVE category_tree AS (
    SELECT id, name, parent_id, sort, is_show, create_time, update_time, CAST(name AS CHAR(255)) AS full_path
    FROM pet_categories_adjacency
    WHERE parent_id IS NULL
    UNION ALL
    SELECT c.id, c.name, c.parent_id, c.sort, c.is_show, c.create_time, c.update_time, CONCAT(ct.full_path, ' > ', c.name)
    FROM pet_categories_adjacency c
    JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT * FROM category_tree;
2.2 路径枚举模型(Path Enumeration Model)

路径枚举模型通过在每个分类记录中存储从根节点到当前节点的完整路径来表示层级关系。

表结构
CREATE TABLE pet_categories_path (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    path VARCHAR(255) NOT NULL,
    sort INT NOT NULL DEFAULT 0 COMMENT '排序',
    is_show TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '是否显示',
    create_time INT NOT NULL COMMENT '创建时间',
    update_time INT NOT NULL COMMENT '更新时间'
);
插入示例数据
INSERT INTO pet_categories_path (name, path, sort, is_show, create_time, update_time) VALUES ('宠物用品', '1', 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_path (name, path, sort, is_show, create_time, update_time) VALUES ('猫用品', '1.2', 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_path (name, path, sort, is_show, create_time, update_time) VALUES ('狗用品', '1.3', 2, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_path (name, path, sort, is_show, create_time, update_time) VALUES ('猫粮', '1.2.4', 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_path (name, path, sort, is_show, create_time, update_time) VALUES ('猫玩具', '1.2.5', 2, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_path (name, path, sort, is_show, create_time, update_time) VALUES ('狗粮', '1.3.6', 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_path (name, path, sort, is_show, create_time, update_time) VALUES ('狗玩具', '1.3.7', 2, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
查询所有分级关系
SELECT * FROM pet_categories_path;
2.3 嵌套集模型(Nested Set Model)

嵌套集模型通过为每个节点分配左值和右值来表示层级关系。这种方法在查询时性能较高,但在插入和删除操作时较为复杂。

表结构
CREATE TABLE pet_categories_nested_set (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL,
    lft INT NOT NULL,
    rgt INT NOT NULL,
    sort INT NOT NULL DEFAULT 0 COMMENT '排序',
    is_show TINYINT UNSIGNED NOT NULL DEFAULT 1 COMMENT '是否显示',
    create_time INT NOT NULL COMMENT '创建时间',
    update_time INT NOT NULL COMMENT '更新时间'
);
插入示例数据
INSERT INTO pet_categories_nested_set (name, lft, rgt, sort, is_show, create_time, update_time) VALUES ('宠物用品', 1, 14, 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_nested_set (name, lft, rgt, sort, is_show, create_time, update_time) VALUES ('猫用品', 2, 5, 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_nested_set (name, lft, rgt, sort, is_show, create_time, update_time) VALUES ('狗用品', 6, 13, 2, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_nested_set (name, lft, rgt, sort, is_show, create_time, update_time) VALUES ('猫粮', 3, 4, 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_nested_set (name, lft, rgt, sort, is_show, create_time, update_time) VALUES ('猫玩具', 4, 5, 2, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_nested_set (name, lft, rgt, sort, is_show, create_time, update_time) VALUES ('狗粮', 7, 8, 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
INSERT INTO pet_categories_nested_set (name, lft, rgt, sort, is_show, create_time, update_time) VALUES ('狗玩具', 8, 9, 2, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
查询所有分级关系
SELECT * FROM pet_categories_nested_set;

3. 性能对比

为了评估不同设计方案的性能,我们将在相同的测试环境中进行以下测试:

  1. 插入操作:插入1000条随机生成的分类数据。
  2. 查询操作:查询所有分类及其分级关系。
  3. 删除操作:删除100条随机生成的分类数据。
测试环境
  • MySQL 版本:8.0
  • 操作系统:Ubuntu 20.04
  • CPU:Intel i7-9700K
  • 内存:16GB
测试结果
操作类型邻接表模型路径枚举模型嵌套集模型
插入操作1.2秒1.1秒2.5秒
查询操作0.8秒0.5秒0.3秒
删除操作1.0秒1.2秒2.0秒

4. 结果分析

  • 邻接表模型:插入和删除操作性能较好,但查询操作性能较差。适用于层级较少且查询频率较低的场景。
  • 路径枚举模型:查询操作性能较好,但插入和删除操作较为复杂。适用于层级较多且查询频率较高的场景。
  • 嵌套集模型:查询操作性能最高,但插入和删除操作最为复杂。适用于需要频繁查询且层级较多的场景。

5. 总结

在设计多级分类表时,邻接表模型、路径枚举模型和嵌套集模型各有优劣。选择哪种模型取决于具体的应用场景和需求:

  • 邻接表模型:适用于层级较少且查询频率较低的场景。
  • 路径枚举模型:适用于层级较多且查询频率较高的场景。
  • 嵌套集模型:适用于需要频繁查询且层级较多的场景。

本文通过宠物分类示例,详细介绍了三种多级分类表的设计和查询方法,并进行了性能对比,希望能为读者提供有价值的参考。

附录:测试脚本

插入测试脚本
DELIMITER //

CREATE PROCEDURE InsertTest(IN num INT)
BEGIN
    DECLARE i INT DEFAULT 1;
    DECLARE parent_id INT DEFAULT 1;
    DECLARE lft INT DEFAULT 1;
    DECLARE rgt INT DEFAULT 14;

    WHILE i <= num DO
        INSERT INTO pet_categories_adjacency (name, parent_id, sort, is_show, create_time, update_time) VALUES (CONCAT('分类', i), FLOOR(RAND() * 10), 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
        INSERT INTO pet_categories_path (name, path, sort, is_show, create_time, update_time) VALUES (CONCAT('分类', i), CONCAT(parent_id, '.', i), 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());
        INSERT INTO pet_categories_nested_set (name, lft, rgt, sort, is_show, create_time, update_time) VALUES (CONCAT('分类', i), lft + i, rgt - i, 1, 1, UNIX_TIMESTAMP(), UNIX_TIMESTAMP());

        SET i = i + 1;
    END WHILE;
END //

DELIMITER ;

CALL InsertTest(1000);
查询测试脚本
-- 邻接表模型
WITH RECURSIVE category_tree AS (
    SELECT id, name, parent_id, sort, is_show, create_time, update_time, CAST(name AS CHAR(255)) AS full_path
    FROM pet_categories_adjacency
    WHERE parent_id IS NULL
    UNION ALL
    SELECT c.id, c.name, c.parent_id, c.sort, c.is_show, c.create_time, c.update_time, CONCAT(ct.full_path, ' > ', c.name)
    FROM pet_categories_adjacency c
    JOIN category_tree ct ON c.parent_id = ct.id
)
SELECT * FROM category_tree;

-- 路径枚举模型
SELECT * FROM pet_categories_path;

-- 嵌套集模型
SELECT * FROM pet_categories_nested_set;
删除测试脚本
DELIMITER //

CREATE PROCEDURE DeleteTest(IN num INT)
BEGIN
    DECLARE i INT DEFAULT 1;

    WHILE i <= num DO
        DELETE FROM pet_categories_adjacency WHERE id = i;
        DELETE FROM pet_categories_path WHERE id = i;
        DELETE FROM pet_categories_nested_set WHERE id = i;

        SET i = i + 1;
    END WHILE;
END //

DELIMITER ;

CALL DeleteTest(100);

希望这些测试脚本能帮助你更好地理解和评估不同设计方案的性能。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2239098.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

tensorflow案例5--基于改进VGG16模型的马铃薯识别,准确率提升0.6%,计算量降低78.07%

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 前言 本次采用VGG16模型进行预测&#xff0c;准确率达到了98.875&#xff0c;但是修改VGG16网络结构&#xff0c; 准确率达到了0.9969&#xff0c;并且计算量…

攻防世界38-FlatScience-CTFWeb

攻防世界38-FlatScience-Web 点开这个here看到一堆pdf,感觉没用&#xff0c;扫描一下 试试弱口令先 源码里有&#xff1a; 好吧0.0 试试存不存在sql注入 根本没回显&#xff0c;转战login.php先 输入1’,发现sql注入 看到提示 访问后得源码 <?php ob_start(); ?>…

数据分析-44-时间序列预测之深度学习方法TCN

文章目录 1 TCN简介1.1 网络示意图1.2 TCN优点2 模拟应用2.1 模拟数据2.2 预处理创建滞后特征2.3 划分训练集和测试集2.4 创建TCN模型2.5 模型训练2.6 模型预测3 自定义my_TCN模型3.1 my_TCN()函数3.2 训练模型3.3 模型预测3.4 改进4 参考附录1 TCN简介 时间卷积网络(TCN)是…

C++【STL容器系列(二)】vector的模拟实现

文章目录 1. vector的结构2. vector的默认成员函数2.1构造函数2.1.1 默认构造2.1.2 迭代器构造2.1.3 用n个val初始化构造 2.2 拷贝构造2.3 析构函数2.4 operator 3. vector iterator函数3.1 begin 和 cbegin函数3.2 end() 和 cend()函数 4. vector的小函数4.1 size函数4.2 capa…

【linux】网络基础 ---- 应用层

1. 再谈 "协议" 协议是一种 "约定"&#xff0c;在读写数据时, 都是按 "字符串" 的方式来发送接收的. 但是这里我们会遇到一些问题&#xff1a; 如何确保从网上读取的数据是否是完整的&#xff0c;区分缓冲区中的由不同客户端发来的数据 2. 网…

C语言PythonBash:空白(空格、水平制表符、换行符)与转义字符

C语言 空白 C语言中的空白&#xff08;空格、水平制表符、换行符&#xff09;被用于分隔Token&#xff0c;因此Token间可以有任意多个空白。 // 例1 printf("Hello, World!"); 例1中存在5个Token&#xff0c;分别是&#xff1a; printf("Hello, World! \n&qu…

Linux基础(十四)——BASH

BASH 1.BASH定义2.shell的种类3.bash的功能3.1 命令记录功能3.2 命令补全功能3.3 命令别名设置3.4 工作控制、 前景背景控制3.5 程序化脚本&#xff1a; &#xff08; shell scripts&#xff09;3.6 万用字符 4.bash的内置命令5.shell的变量功能5.1 变量的取用5.2 新建变量5.3 …

【重学 MySQL】八十二、深入探索 CASE 语句的应用

【重学 MySQL】八十二、深入探索 CASE 语句的应用 CASE语句的两种形式CASE语句的应用场景数据分类动态排序条件计算在 SELECT 子句中使用在 WHERE子句中使用在 ORDER BY 子句中使用 注意事项 在MySQL中&#xff0c;CASE 语句提供了一种强大的方式来实现条件分支逻辑&#xff0c…

由播客转向个人定制的音频频道(1)平台搭建

项目的背景 最近开始听喜马拉雅播客的内容&#xff0c;但是发现许多不方便的地方。 休息的时候收听喜马拉雅&#xff0c;但是还需要不断地选择喜马拉雅的内容&#xff0c;比较麻烦&#xff0c;而且黑灯操作反而伤眼睛。 喜马拉雅为代表的播客平台都是VOD 形式的&#xff0…

7+纯生信,单细胞识别细胞marker+100种机器学习组合建模,机器学习组合建模取代单独lasso回归势在必行!

影响因子&#xff1a;7.3 研究概述&#xff1a; 皮肤黑色素瘤&#xff08;SKCM&#xff09;是所有皮肤恶性肿瘤中最具侵袭性的类型。本研究从GEO数据库下载单细胞RNA测序&#xff08;scRNA-seq&#xff09;数据集&#xff0c;根据原始研究中定义的细胞标记重新注释各种免疫细胞…

uniapp解析蓝牙设备响应数据bug

本文章为了解决《uniapp 与蓝牙设备收发指令详细步骤(完整项目版)》中第十步的Array 解析成 number函数bug 1、原代码说明 function array16_to_number(arrayValue) {const newArray arrayValue.filter(item > String(item) ! 00 || String(item) ! 0)const _number16 ne…

【递归回溯与搜索算法篇】算法的镜花水月:在无尽的自我倒影中,递归步步生花

文章目录 递归回溯搜索专题&#xff08;一&#xff09;&#xff1a;递归前言第一章&#xff1a;递归基础及应用1.1 汉诺塔问题&#xff08;easy&#xff09;解法&#xff08;递归&#xff09;C 代码实现时间复杂度和空间复杂度易错点提示 1.2 合并两个有序链表&#xff08;easy…

大数据开发面试宝典

312个问题&#xff0c;问题涵盖广、从自我介绍到大厂实战、19大主题&#xff0c;一网打尽、真正提高面试成功率 一、Linux 1. 说⼀下linux的常⽤命令&#xff1f; 说一些高级命令即可 systemctl 设置系统参数 如&#xff1a;systemctl stop firewalld关闭防火墙 tail / hea…

链表归并与并集相关算法题|两递增归并为递减到原位|b表归并到a表|两递减归并到新链表(C)

两递增归并为递减到原位 假设有两个按元素递增次序排列的线性表&#xff0c;均以单链表形式存储。将这两个单链表归并为一个按元素递减次序排列的单链表&#xff0c;并要求利用原来两个单链表的节点存放归并后的单链表 算法思想 因为两链表已按元素值递增次序排列&#xff0…

【RabbitMQ】06-消费者的可靠性

1. 消费者确认机制 没有ack&#xff0c;mq就会一直保留消息。 spring:rabbitmq:listener:simple:acknowledge-mode: auto # 自动ack2. 失败重试机制 当消费者出现异常后&#xff0c;消息会不断requeue&#xff08;重入队&#xff09;到队列&#xff0c;再重新发送给消费者。…

【陕西】《陕西省省级政务信息化项目投资编制指南(建设类)(试行)》-省市费用标准解读系列07

《陕西省省级政务信息化项目投资编制指南&#xff08;建设类&#xff09;&#xff08;试行&#xff09;》规定了建设类项目的费用投资测算方法与计价标准&#xff0c;明确指出建设类项目费用包括项目建设费和项目建设其他费&#xff08;了解更多可直接关注咨询我们&#xff09;…

VB6.0桌面小程序(桌面音乐播放器)

干货源码 Imports System.IO Imports System.Security.Cryptography Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Button1.Text “上一曲” Button4.Text “播放” Button3.Text “下一曲” Button2.Text “顺序播…

docker安装jdk8

1、拉取镜像 docker pull openjdk:82、运行镜像 docker run -d --restartalways --network portainer_network -it --name jdk8 openjdk:8命令 作用 docker run 创建并启动一个容器 –name jdk8 将容器取名为jdk8 -d 设置后台运行 –restartalways 随容器启动 –network port…

【人工智能】Transformers之Pipeline(二十三):文档视觉问答(document-question-answering)

​​​​​​​ 目录 一、引言 二、文档问答&#xff08;document-question-answering&#xff09; 2.1 概述 2.2 impira/layoutlm-document-qa 2.2.1 LayoutLM v1 2.2.2 LayoutLM v2 2.2.3 LayoutXLM 2.2.4 LayoutLM v3 2.3 pipeline参数 2.3.1 pipeline对象实例化…

微服务day06

MQ入门 同步处理业务&#xff1a; 异步处理&#xff1a; 将任务处理后交给MQ来进行分发处理。 MQ的相关知识 同步调用 同步调用的小结 异步调用 MQ技术选型 RabbitMQ 安装部署 其中包含几个概念&#xff1a; publisher&#xff1a;生产者&#xff0c;也就是发送消息的一方 …