MySQL無限極分類數據表的設計

 

 

 

 

 

 

無限級分類表設計

   實際上我們在開發過程中,就拿商品類別來說,它還可以有更多的延伸,我們先來舉一個簡單的例子,比如圖書,他的下面還可以分小說、文學等,在小說下面還可以分爲言情小說、科幻小說等,還可以再往下一級一級繼續分,那麼這種分類就屬於無限極分類,那麼無限極分類表該如何去設計,理論上說我們可以設計很多張表,但是隨着分類的逐步增多,表的數目就會越來越多,所以無限極分類表往往採用另外一種形式。

 

 

  我們先來看一下它的語法結構。

CREATE TABLE tdb_goods_types(
type_id   SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
type_name VARCHAR(20) NOT NULL,
parent_id SMALLINT UNSIGNED NOT NULL DEFAULT 0
 ); 

  這種數據表至少存在3個字段,第一個是分類的id,第二個字段是分類的名稱,第三個字段是他父類的id,也就是說他實際上是通過自身的連接來實現的。


  現在我們就先創建這張表,操作命令及結果如下:

CREATE TABLE tdb_goods_types(
     type_id   SMALLINT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
     type_name VARCHAR(20) NOT NULL,
     parent_id SMALLINT UNSIGNED NOT NULL DEFAULT 0
  );

 

 

 

 

 

  現在我們插入幾條我們事先準備好的數據,命令如下:


  INSERT tdb_goods_types(type_name,parent_id) VALUES('家用電器',DEFAULT);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('電腦、辦公',DEFAULT);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('大家電',1);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('生活電器',1);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('平板電視',3);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('空調',3);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('電風扇',4);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('飲水機',4);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('電腦整機',2);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('電腦配件',2);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('筆記本',9);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('超級本',9);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('遊戲本',9);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('CPU',10);
  INSERT tdb_goods_types(type_name,parent_id) VALUES('主機',10);

OK,插入成功之後。

 

 

 

 

 

  下面我們來查看一下里邊的記錄,我們輸入SELECT * FROM  tdb_goods_types;


  那麼後面的數字表示什麼意思呢?

比如這個家用電器的0就表示他沒有父親節點,爲頂級分類,再比如大家電後面的1就表示它的父親節點是id號爲1的家用電器

  這就是無限極分類的數據表,但是這裏邊就涉及到另外一個問題,我們該怎麼做查找。

  要做查找的話,我們就需要通過自身連接來實現,所謂自身連接,就是指數據表自己來連接自己,下面我們來做一個簡單的演示,我們還以剛纔那個表爲例,比如我要查找所有子類的父類,比如家用電器他的父類是什麼?如果沒有就是NULL,那麼這就需要大家有一點想象力,就是在這張表的右側還有一張跟他結構完全一樣的數據表。假設我們把左邊的當成父表,右邊的當成子表,那麼我們左邊的父表中的parent_id這個字段就沒有什麼用了。


  下面我們來看看該怎麼寫,這裏邊就一定要起別名了,因爲所有的字段都是相同的,我們就把子表取爲s,父表取爲p,具體操作命令及結果如下:

 

  Ok,這樣我們就查到了子類所對應的父類的名字。沒有父類的就爲NULL.當然這裏我們只能查到他的一級父類,mysql暫時還沒有遞歸查詢的能力,後面我們可以通過程序來實現。  

 

 

 

 

  下面我們再來查找一下子類的父類,以及父類下面的子類,這裏只是參照的表不同而已,比如這次我們把左邊的當子表,右邊的當父表,分組排序操作命令及結果如下:


注:我在分組的時候出現過一個錯誤:

Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'test2.p.type_id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by

可以去除only_full_group_by;登錄數據庫後敲以下代碼,回車,繼續分組就好了:

set @@sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';


  那麼現在如果我想要父類下面子類的數目。那麼該怎麼辦呢?我們只需要對子類數目做一下統計。

  現在我們想要子類的數目而不是子類的名字,那麼我們只需要做一個計數,我們簡單修改一下。修改後的命令及結果如下:


   OK,這就是我們想要的。這也就是通過自身連接來實現的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章