通常說到無限級分類、菜單之類的東西,你們 (我) 的數據表設計通常是這樣的html
id | parent_id | title | 更多字段... |
---|---|---|---|
1 | 0 | 衣物 | ... |
2 | 1 | 上衣 | ... |
3 | 1 | 褲子 | ... |
4 | 3 | 西褲 | ... |
5 | 4 | 長西褲 | ... |
6 | 4 | 短西褲 | ... |
7 | 2 | 襯衫 | ... |
其中,parent_id
表示父分類的id。由此可知,衣物分類下有上衣和褲子兩個二級分類;而褲子還有西褲這個三級分類……以此類推sql
這種設計比較常見 (就我所知),但缺點很明顯。
例如須要顯示例以下面這樣的麪包屑導航時:衣物 > 褲子 > 西褲
就不得不進行屢次循環設計
再例如,須要顯示全部分類並表示層級時:code
<select name="" id=""> <option value="">衣物</option> <option value="">--> 褲子</option> <option value="">--> --> 西褲</option> <option value="">--> --> --> 長西褲</option> <option value="">--> --> --> 短西褲</option> <option value="">--> 上衣</option> <option value="">--> --> 襯衫</option> </select>
也不得不進行屢次循環htm
那麼,如何快速實現上述的常見功能呢?get
首先,示例表設計:博客
id | title | path | level | 更多字段... |
---|---|---|---|---|
1 | 衣物 | 0 | 0 | ... |
2 | 上衣 | 0,1 | 1 | ... |
3 | 褲子 | 0,1 | 1 | ... |
4 | 西褲 | 0,1,3 | 2 | ... |
5 | 長西褲 | 0,1,3,4 | 3 | ... |
6 | 短西褲 | 0,1,3,4 | 3 | ... |
7 | 襯衫 | 0,1,2 | 2 | ... |
其中,path
表示父級id列表。例如西褲的0,1,3
就表示衣物 > 褲子
實現麪包屑時只要取出path
字段的值,而後用,
分割,獲得id列表
再用where id in (1,3)
便可it
須要顯示全部分類並表示層級時,使用下面的SQL:io
SELECT *,concat(path,',',id) AS paths FROM menu ORDER BY paths
看到的結果是這樣的:table
id | title | path | level | paths |
---|---|---|---|---|
1 | 衣物 | 0 | 0 | 0,1 |
2 | 上衣 | 0,1 | 1 | 0,1,2 |
7 | 襯衫 | 0,1,2 | 2 | 0,1,2,7 |
3 | 褲子 | 0,1 | 1 | 0,1,3 |
4 | 西褲 | 0,1,3 | 2 | 0,1,3,4 |
5 | 長西褲 | 0,1,3,4 | 3 | 0,1,3,4,5 |
6 | 短西褲 | 0,1,3,4 | 3 | 0,1,3,4,6 |
那麼,直接取出結果輸出便可。level
字段就是層級的意思
例如在PHP中,能夠用str_repeat('--> ', $level)
直接輸出表示層級的前綴
而且連順序都排好了,是否是很方便呢?
本文首發於個人博客 超能小紫,若是喜歡請常來玩哦