后端树结构分类数据模型如何设计

树形结构在后端系统中非常常见,特别是分类管理场景,例如商品分类、组织架构等。本文将以给定的数据库表为例,探讨如何设计树结构分类数据模型及其优点。

一、数据表设计

1. 分类节点表

CREATE TABLE `product_classification_node` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键(分类ID)',
  `classification_name` varchar(50) NOT NULL DEFAULT '' COMMENT '分类名称',
  `parent_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT '分类父ID',
  `classification_desc` varchar(511) NOT NULL DEFAULT '' COMMENT '分类描述',
  `is_enabled` tinyint(1) NOT NULL DEFAULT '-1' COMMENT '是否启用 | 0:未启用 1:启用',
  `create_user_id` varchar(50) NOT NULL DEFAULT '' COMMENT '创建用户id',
  `create_user_name` varchar(20) NOT NULL DEFAULT '' COMMENT '创建用户姓名',
  `update_user_id` varchar(50) NOT NULL DEFAULT '' COMMENT '更新用户id',
  `update_user_name` varchar(20) NOT NULL DEFAULT '' COMMENT '更新用户姓名',
  `time_update` bigint(20) NOT NULL COMMENT '更新时间',
  `time_create` bigint(20) NOT NULL COMMENT '创建时间',
  `product_count` int(11) NOT NULL DEFAULT '0' COMMENT '商品数量',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_name_pid` (`parent_id`,`classification_name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分类节点表';

该表主要记录分类的基本信息和层级关系,通过parent_id字段表示父子关系。

2. 闭包表

CREATE TABLE `product_classification_node_closure` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `descendant_id` bigint(20) NOT NULL COMMENT '后代节点 ID',
  `ancestor_id` bigint(20) NOT NULL COMMENT '祖先节点 ID',
  `depth` tinyint(3) NOT NULL COMMENT '祖先节点到后代节点的层数差',
  `time_update` bigint(20) NOT NULL COMMENT '更新时间',
  `time_create` bigint(20) NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_ancestorid_descendantid` (`ancestor_id`,`descendant_id`),
  KEY `k_descendantid` (`descendant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分类节点闭包表';

闭包表记录了每个节点与其所有祖先和后代的关系,depth字段表示层级差。

3. 分类商品关联表

CREATE TABLE `classification_product` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
  `productclassificationnode_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT '分类表主键ID',
  `product_id` bigint(20) NOT NULL DEFAULT '-1' COMMENT 'product 表主键ID',
  `product_code` int(11) NOT NULL DEFAULT '-1' COMMENT '商品编码',
  `create_user_id` varchar(50) NOT NULL DEFAULT '' COMMENT '创建用户id',
  `create_user_name` varchar(20) NOT NULL DEFAULT '' COMMENT '创建用户姓名',
  `update_user_id` varchar(50) NOT NULL DEFAULT '' COMMENT '更新用户id',
  `update_user_name` varchar(20) NOT NULL DEFAULT '' COMMENT '更新用户姓名',
  `time_update` bigint(20) NOT NULL COMMENT '更新时间',
  `time_create` bigint(20) NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `uk_procutid_nodeid` (`product_id`,`productclassificationnode_id`),
  KEY `k_productclassificationnodeid_areazip` (`productclassificationnode_id`,`area_zip`),
  KEY `k_productcode_areazip` (`product_code`,`area_zip`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='分类商品表';

此表实现商品与分类节点的关联,支持快速查询商品所属分类。


二、设计原则与实现

  1. 清晰的层级关系:
    • product_classification_node中,通过parent_id实现父子节点关系。数据插入时即可构建树状结构。
    • 使用product_classification_node_closure闭包表,便于快速查询某一节点的所有祖先或后代,优化层级遍历性能。
  2. 性能优化:
    • 闭包表的优势:
      • 单表无法高效支持深层次树结构查询(例如查询所有祖先节点)。
      • 闭包表提前存储了节点间的路径信息,使查询复杂度由递归降为单表查询。
    • 索引设计:
      • 主键索引与UNIQUE KEY保证数据唯一性,防止重复插入。
      • 针对高频查询字段设置索引,例如ancestor_iddescendant_id,支持多级分类的高效查询。
  3. 灵活的商品关联:
    • classification_product表支持商品与分类多对多关系管理,灵活应对商品多分类场景。
    • 索引uk_procutid_nodeidk_productclassificationnodeid_areazip便于快速定位商品分类和地域维度。

三、常见功能实现

  1. 获取分类树:

    SELECT * FROM product_classification_node
    WHERE is_enabled = 1;
    
    • 根据parent_id递归构建树。
  2. 查询某分类的所有后代:

    SELECT descendant_id FROM product_classification_node_closure
    WHERE ancestor_id = ?;
    
  3. 查询某分类的所有祖先:

    SELECT ancestor_id FROM product_classification_node_closure
    WHERE descendant_id = ?;
    
  4. 统计分类下商品数量:

    SELECT SUM(product_count) FROM product_classification_node_closure c
    JOIN product_classification_node n ON c.descendant_id = n.id
    WHERE c.ancestor_id = ?;
    

四、设计优点

  1. 高效的层级查询:
    • 闭包表避免了递归查询的性能问题。
    • 适用于需要频繁查询祖先、后代节点的场景。
  2. 灵活扩展性:
    • 支持复杂分类树形结构的动态调整,例如新增、删除、移动节点。
    • 商品与分类的多对多设计满足不同业务需求。
  3. 清晰的结构:
    • 分类节点、闭包表、商品关联分表设计,分工明确,便于维护和扩展。
  4. 稳定性:
    • 完整的索引设计与唯一约束减少数据一致性问题。

五、适用场景

  • 商品分类管理系统
  • 组织架构管理
  • 内容管理系统(CMS)中的栏目分类
  • 权限管理中的资源树

通过这样的设计,不仅能够满足树结构数据模型的基本需求,还具备良好的性能和扩展性,适合于复杂的后端分类管理场景。

你可能感兴趣的:(历史经验篇,分类,数据库,java)