一種更為高效的資料庫無限級分類表設計

2021-10-24 14:03:01 字數 3390 閱讀 6204

一般地,大家在資料庫設計無限級分類表時只是多新增了乙個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

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(裙子)/』)

查詢所有衣服只要使用查詢條件「alias=『clothing』」。

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...