MySQL之無限級分類表設計


 

首先查找一下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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM