首先查找一下goods_cates表和table_goods_brands数据表

分别使用命令:

root@localhost test>show columns from goods_cates;
root@localhost test>select * from goods_cates;

1、无限分级表设计
但这仅仅是示例,远远达不到实际的需求,比如说书籍这个类,在网站上可以搜索到在书籍这个分类下面还有历史,文学,经济等等子类,子类下面还有子类,这种无限分类如何设计呢?理论上可以设计很多张表,随着分类的增多,这些数据表不可能无限扩展,因此可以通过如下设计:

CREATE TABLE table_goods_type(
    type_id SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
type_name VARCHAR(20) NOT NULL,
parent_id SMALLINT UNSIGNED NOT NULL DEFAULT 0
);
创建成功之后查看一下

root@localhost test>show columns from table_goods_type;

现在插入若干条记录

INSERT table_goods_type(type_name,parent_id) VALUES ('家用电器',DEFAULT);
INSERT table_goods_type(type_name,parent_id) VALUES ('电脑办公',DEFAULT);
INSERT table_goods_type(type_name,parent_id) VALUES ('大家电',1);
INSERT table_goods_type(type_name,parent_id) VALUES ('生活电器',1);
INSERT table_goods_type(type_name,parent_id) VALUES ('平板电视',3);
INSERT table_goods_type(type_name,parent_id) VALUES ('空调',3);
INSERT table_goods_type(type_name,parent_id) VALUES ('电风扇',4);
INSERT table_goods_type(type_name,parent_id) VALUES ('饮水机',4);
INSERT table_goods_type(type_name,parent_id) VALUES ('电脑整机',2);
INSERT table_goods_type(type_name,parent_id) VALUES ('电脑配件',2);
INSERT table_goods_type(type_name,parent_id) VALUES ('笔记本',9);
INSERT table_goods_type(type_name,parent_id) VALUES ('超极本',9);
INSERT table_goods_type(type_name,parent_id) VALUES ('游戏本',9);
INSERT table_goods_type(type_name,parent_id) VALUES ('CPU',10);
INSERT table_goods_type(type_name,parent_id) VALUES ('主机',10);
 查询一下记录
root@localhost test>select * from table_goods_type;

关于parent_id的说明:

1、parent_id为0,家用电器为顶级结点,意味着就是没有父亲结点,因此就是为0,同电脑办公也是父亲节点

2、大家电作为家用电器的子类,所以其父类为家用电器的type_id,所以写的是1,同生活电器

3、而平板电视属于大家电的子类,因此其parent_id为3,同样饮水机属于生活电器,因此parent_id为4,依次类推

上述的表设计好了之后如何做查找呢?

要做查找的话就需要通过自身连接来实现,所谓自身连接就是数据连接并不是其他数据表,而是自身。

现在想查找所有的子类和其父类,如何操作呢?要是有两张表,可以很容易知道,但是现在一张表怎么实现呢,想象右侧也有一张表,这张表示子表

因为子表中的parent_id指向的是父表中的type_id

root@localhost test> SELECT son.type_id,son.type_name,parent.type_name FROM table_goods_type AS son
-> LEFT JOIN table_goods_type AS parent
-> ON son.parent_id = parent.type_id;

因为家电电器和电脑办公属于顶级分类,因此其没有父类,其它的均可以查找到父类,因为MySQL没有递归查询的能力,因此只能查找到一级分类。既然能查到子类的id(type_id),子类的名字name(type_name)和父类的名字type_name.

root@localhost test>SELECT parent.type_id,parent.type_name,son.type_name FROM table_goods_type parent LEFT JOIN
-> table_goods_type son ON son.parent_id = parent.type_id;

这样就查到了左边和右边两个类,左边是家用电器这个类,其子类有大家电和生活电器,大家电下面有子类平板电视和空调,依次类推,当然像主机、CPU下面就没有子类,所以为NULL。由于左边的父类显示有重复的,这里进行修改

root@localhost test>SELECT parent.type_id,parent.type_name,son.type_name FROM table_goods_type parent LEFT JOIN
-> table_goods_type son ON son.parent_id = parent.type_id GROUP BY parent.type_name;

root@localhost test>SELECT parent.type_id,parent.type_name,son.type_name FROM table_goods_type parent LEFT JOIN
-> table_goods_type son ON son.parent_id = parent.type_id GROUP BY parent.type_name
-> ORDER BY parent.type_id;

现在只显示子类的数目,不显示子类的名字

root@localhost test>SELECT parent.type_id,parent.type_name,count(son.type_name) child_count FROM table_goods_type parent LEFT JOIN
-> table_goods_type son ON son.parent_id = parent.type_id GROUP BY parent.type_name
-> ORDER BY parent.type_id;

这样就只显示了子类的数量

2、多表的删除
多表的删除的语法结构是

DELETE table_name[.*] [,table_name[.*]]... FROM table_references [WHERE where_condition]

在表goods中发现有两条重复的记录,分别是honorX6和Laserjet Pro P16重复,可能在有意无意键录入了重复的记录,现在想删除重复的记录,保留goods_id较小的那个,这就是通过多表删除实现,采用一张表模拟两张表的方法实现,首先要查找重复的记录。

root@localhost test>SELECT goods_id,goods_name FROM goods GROUP BY goods_name;

总共11条记录,现在分组筛选之后还有9条,说明重复了2条,但是只想要记录重复(超过两个以上的),因此可以是HAVING

root@localhost test>SELECT goods_id,goods_name FROM goods GROUP BY goods_name HAVING count(goods_name) >= 2;

这两条记录就是重复的,就是需要删除的,因此可以参照这张表删除初始的表goods

root@localhost test>DELETE t1 FROM goods AS t1 LEFT JOIN (SELECT goods_id,goods_name FROM goods GROUP BY
-> goods_name HAVING count(goods_name) >= 2) AS t2 ON t1.goods_name = t2.goods_name WHERE t1.goods_id > t2.goods_id;

提示两条记录被删除,再来查看一下表goods

3.根据子类id查找顶级id

<?php
$list = "select id, pid from tablename ";
// 查询后 将结果处理成 如下数组格式
$arr = aray_column($list,'pid','id');
$arr = [
// id => pid
=> 0,
// 省略...
=> 1,
// 省略...
=> 5
];
// 建议将这数组缓存起来 $id = 13;
while($arr[$id]) {
$id = $arr[$id];
}
echo $id; //

原文:https://blog.csdn.net/rhx_qiuzhi/article/details/79936575

MySQL之无限级分类表设计的更多相关文章

  1. MySQL技巧(二)——无限级分类表设计

    无限级分类表的设计(掌握'自身连接') 类似图书这种,会有很多种分类,而且在现实生活中这种分类会无限的往下分,所以不可能每有一个分类就创建一个分类表.应该使用下面这种语句 DROP TABLE IF ...

  2. FreeSql 使用 ToTreeList/AsTreeCte 查询无限级分类表

    关于无限级分类 第一种方案: 使用递归算法,也是使用频率最多的,大部分开源程序也是这么处理,不过一般都只用到四级分类. 这种算法的数据库结构设计最为简单.category表中一个字段id,一个字段fi ...

  3. mysql status关键字 数据表设计中慎重使用

    mysql status关键字  数据表设计中慎重使用

  4. MySQL分类表设计--根据ID删除全部子类

    在做数据库分类表的时候,通常会有这样的设计:一个字段是ID,另一个字段PID,PID指向自己的上级分类: 这样的设计带来的问题是:我要删除一个类,我希望它的子类全部一起删除: 在不知道分类有多少层级的 ...

  5. MySQL进阶:约束,多表设计,多表查询,视图,数据库备份与还原

    MySQL进阶 知识点梳理 一.约束 1. 外键约束 为什么要有外键约束 例如:一个user表,一个orderlist 如果现在想要直接删除id为1的张三,但是orderlist里还有用户id为1的订 ...

  6. 转:php+mysql菜单无限级分类(非递归)

    php+mysql无限级分类(非递归) 参考:http://www.chhua.com/web-note3244

  7. mysql系列十一、mysql优化笔记:表设计、sql优化、配置优化

    可以从这些方面进行优化: 数据库(表)设计合理 SQL语句优化 数据库配置优化 系统层.硬件层优化 数据库设计 关系数据库三范式 1NF:字段不可分; 2NF:有主键,非主键字段依赖主键; 3NF:非 ...

  8. 转一篇MYSQL文章《数据库表设计,没有最好只有最适合》

    http://mp.weixin.qq.com/s/a8klpzM5iam0_JYSw7-U4g 我们在设计数据库的时候,是否会突破常规,找到最适合自己需求的设计方案,下面来举个例子: 常用的邻接表设 ...

  9. mysql myisam简单分表设计

    一般来说,当我们的数据库的数据超过了100w记录的时候就应该考虑分表或者分区了,这次我来详细说说分表的一些方法.目前我所知道的方法都是MYISAM的,INNODB如何做分表并且保留事务和外键,我还不是 ...

随机推荐

  1. easyUI的datagrid控件日期列格式化

    转自:https://blog.csdn.net/idoiknow/article/details/8136093 EasyUI是一套比较轻巧易用的Jquery控件,在使用过程中遇到一个问题,它的列表 ...

  2. 关于一次同余方程的一类解法(exgcd,CRT,exCRT)

    1.解同余方程: 同余方程可以转化为不定方程,其实就是,这样的问题一般用拓展欧几里德算法求解. LL exgcd(LL a,LL b,LL &x,LL &y){ if(!b){ x=; ...

  3. canvas基础知识点(一)

    给canvas设置宽高: canvas标签的宽高默认是300*150,是一个行内块元素 可以在canvas标签上通过width,height来设置 可以在js中给dom对象设置: mycanvas.w ...

  4. flask 第六篇 flask内置的session

    Flask中的Session非常的奇怪,他会将你的SessionID存放在客户端的Cookie中,使用起来也非常的奇怪 1. Flask 中 session 是需要 secret_key 的 from ...

  5. smarty中ifelse、foreach以及获取数组中键值名的一个实例

    <{if empty($history)}> <tr> <td colspan="6">Not any records!</td> ...

  6. Mac下制作openwrt U盘启动盘

    华硕路由用腻了,正好家里有老旧淘汰的电脑,那么非常适合折腾一下OpenWrt,科学上网靠自己. 什么是OpenWrt:OpenWrt是适合于嵌入式设备的一个Linux发行版. 参考资料:https:/ ...

  7. 给JAVA的eclipse IDE 在线安装 SVN插件 / 给 eclipse 添加打开所在的文件夹功能

    http://subclipse.tigris.org/servlets/ProjectProcess?pageID=p4wYuA 首先,在这个网址找着最新在线安装链接 就是那个 Links for ...

  8. Fiddler Wireshark 抓包

    使用 层次 Fiddler 简单 第七层应用层的 HTTP(S) 协议的包 Wireshark 复杂 第三层网络层的包 注意:Fiddler 只能抓到走系统代理的流量.不走系统代理的流量(比如浏览器选 ...

  9. nodejs相关

    安装: 1:下载 Node.js 安装包及源码下载地址为:https://nodejs.org/en/download/. 32 位安装包下载地址 : https://nodejs.org/dist/ ...

  10. koa express 优缺点

    关于 Express 优点.Express 的优点是线性逻辑:路由和中间件完美融合,通过中间件形式把业务逻辑细分,简化,一个请求进来经过一系列中间件处理后再响应给用户,再复杂的业务也是线性了,清晰明了 ...