一般地,大家在資料庫設計無限級分類表時只是多新增了乙個parent_id欄位,這樣如果要讀取所有分類的話只能進行遞迴讀取資料庫表操作,這樣的效能可想而知。
先看個表及測試資料:
idname
parent_id
1clothing(衣服)02
men』s(**)13
women』s(**)14
suits(套裝)25
dresses(連衣裙)36
skirts(裙子)37
blouses( 女襯衫)38
slacks( 長褲)49
jackets(夾克)410
evening gowns( 晚禮服)511
sun dresses( 太陽裙)
6為了更高效地查詢和使用無限級分類表,我們增加了如下幾個字段:
id_path:從根節點到本節點的所有id,如上表所示id為1的id_path為「.1.」,id為5的id_path為「.1.3.5.」,所有id用英文句號「.」包圍和隔開。
parent_id_path:參考id_path,不包括當前id。
name_path:對應id_path的分類名稱路徑,用「/」包圍和隔開,如id為1的name_path為「/衣服/」,id為5的name_path為「/衣服/**/連衣裙/」。
order_weight:分類排序權重。
alias:分類別名,如果有多重分類放在同乙個表,可以使用alias區分,如衣服的分類和區劃的分類放在同乙個表,衣服的alias為「clothing」,區劃的分類為「area」。 id
name
parent_id
id_path
parent_id_path
name_path
order_weight
alias
1clothing(衣服)
0.1.
/clothing(衣服)/
0clothing
2men』s(**)
1.1.2.
.1./clothing(衣服)/men』s(**)/
0clothing
3women』s(**)
1.1.3.
.1./clothing(衣服)/women』s(**)/
0clothing
4suits(套裝)
2.1.2.4.
.1.2.
/clothing(衣服)/men』s(**)/ suits(套裝)/
0clothing
5dresses(連衣裙)
3.1.3.5.
.1.3.
/clothing(衣服)/women』s(**)/dresses(連衣裙)/
0clothing
6skirts(裙子)
3.1.3.6.
.1.3.
/clothing(衣服)/women』s(**)/skirts(裙子)/
0clothing
7blouses( 女襯衫)
3.1.3.7.
.1.3.
/clothing(衣服)/women』s(**)/blouses( 女襯衫)/
0clothing
8slacks( 長褲)
4.1.2.4.8.
.1.2.4.
/clothing(衣服)/men』s(**)/suits(套裝)/ slacks( 長褲)/
0clothing
9jackets(夾克)
4.1.2.4.9.
.1.2.4.
/clothing(衣服)/men』s(**)/suits(套裝)/jackets(夾克)/
0clothing
10evening gowns( 晚禮服)
5.1.3.5.10.
.1.3.5.
/clothing(衣服)/women』s(**)/ dresses(連衣裙)/evening gowns( 晚禮服)/
0clothing
11sun dresses( 太陽裙)
6.1.3.6.11.
.1.3.6.
/clothing(衣服)/women』s(**)/skirts(裙子)/sun dresses( 太陽裙)/
0clothing
12全國
0.12.
/全國/
0area
13北京
12.12.13.
.12.
/全國/北京/
0area
這樣設計後,
如果要獲取某個分類下的所有分類,只需使用查詢條件「id_path like 『%』」即可查詢到結果,如要查詢所有**,可以使用查詢條件「id_path like 『.1.3.%』」得到所有**的分類。
如果要嚴格按id呈樹形層級排序,只需使用「order by id_path asc」,得到的查詢結果可直接顯示到選擇列表;或者通過程式按id_path組織成需要的資料格式(用迴圈,不用遞迴)。
如果要嚴格呈樹形層級排序,且各級按排序權重order_weight排序,則使用「order by parent_id_path asc, order_weight desc」,然後按id_path組織成需要的資料格式(用迴圈,不用遞迴)。
按多個分類id使用「where in(id1, id2, …)」查詢所有當前分類及子分類仍然可以通過程式重新組織成所需要的資料格式,參考2、3。
如果要獲取分類的麵包屑導航,只要讀取id_path和name_path進行處理即可。
如果要編輯移動分類,比如把id為5的「連衣裙」移動到id為6的「裙子」下面,需要把屬於「連衣裙」的分類及子分類的id_path的「.1.3.」字首替換成「.1.3.6.」,把屬於「連衣裙」的分類及子分類的name_path的「/clothing(衣服)/women』s(**)/」字首替換成「/clothing(衣服)/women』s(**)/skirts(裙子)/」。sql操作為:
set查詢所有衣服只要使用查詢條件「alias=『clothing』」。parent_id=6,
id_path=replace(id_path, 『.1.3.』, 『.1.3.6.』),
parent_id_path=replace(parent_id_path, 『.1.3.』, 『.1.3.6.』),
name_path=replace(name_path, 『/clothing(衣服)/women』s(**)/』, 『/clothing(衣服)/women』s(**)/skirts(裙子)/』)
id、name、parent_id、id_path、parent_id_path都可以設定索引。
PHP單次資料庫查詢實現無限級分類
這裡使用一張簡單的地區表舉例,表字段如下 使用sql select id,parentid,name from area 查詢得出的資料形如 array 3362 1 array 3 2 array 3 3 array 3 4 array 3 使用函式xmsb getdatatree desc xm...
用C 和資料庫實現無限級分類法
在做軟體是,碰上這個問題,要把乙個商店的分類用樹形來表示。商品分類應該是無限子類劃分的,怎樣設計好一些。用資料庫還是用xml。由於以前搞設計,程式設計方面較生了,也則開始學,覺得還是用資料庫比較熟悉些。由於以前沒這方面經驗,所以對資料庫設計感到比較竦手。想了很多,比如鍊錶,用乙個parent 父關係...
收集 各式各樣的 無限級分類 的資料庫設計方案
第一種方案 表為兩張,一張分類表,一張資訊表。表1 id int 10 cid tinyint 3 title varchar 255 表2 cid tinyint 3 parentid tinyint 3 order tinyint 3 name varchar 255 這樣可以根據cid par...