2010-03-25 66 views
9

我試圖建立一個使用具有層次結構的類別表的導航系統。MySQL&PHP - 創建多個父子關係

id (int) - Primary key 
name (varchar) - Name of the Category 
parentid (int) - Parent ID of this Category referenced to same table (Self Join) 

但美中不足的是,我需要一個類別可孩子多個父類..就像一個已經和屬於多個(HABTM)關係:通常情況下,如下表將被定義。

我知道,如果有兩個表,類別&項,我們使用連接表categories_items列出HABTM關係。但在這裏,我沒有兩張桌子,而只有桌子,但應該以某種方式向自己展示HABTM關係。這是可以使用單個表嗎?如果是,如何?如果不可能,在創建附加連接表時應遵循哪些規則(表名,字段)?

我試圖用CakePHP來實現這個功能,如果有人可以爲這個問題提供CakePHP解決方案,那就太棒了。即使這是不可能的,任何關於創建連接表的解決方案都是值得讚賞的。謝謝你的時間。

- 編輯 - 我的問題似乎有點混亂,所以我試圖重申我在找什麼。 在傳統的自引用(自連接)父子關係中,每個項目只能有一個父項。我在尋找的是模擬一個HABTM關係,即每個項目的多個父母。

類別&項目 - 要定義HABTM,我們使用categories_items連接表。

如果在類別內我需要HABTM,我該怎麼辦?

+0

u能在一個領域被分隔它們用逗號或一些分隔符 – 2010-03-25 11:00:29

+0

+1有趣的問題:-) – richsage 2010-03-25 11:04:54

+0

我發現這個而谷歌搜索,http://n2.nabble.com/Saving-self-保存多值參考-HABTM-關係-td1126141.html,我試圖複製相同的,但仍然蛋糕沒有捕捉關聯。任何想法,有人? – Ashok 2010-03-29 11:13:56

回答

0

明白了最後。

Naviitems表:

CREATE TABLE IF NOT EXISTS `naviitems` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `name` varchar(50) NOT NULL, 
    `linkurl` varchar(250) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

自聯接表:

CREATE TABLE IF NOT EXISTS `naviitems_parents` (
    `id` int(11) NOT NULL AUTO_INCREMENT, 
    `naviitem_id` int(11) NOT NULL, 
    `parent_id` int(11) NOT NULL, 
    PRIMARY KEY (`id`) 
); 

Naviitems型號:

<?php 
class Naviitem extends AppModel { 

    var $name = 'Naviitem'; 

    //The Associations below have been created with all possible keys, those that are not needed can be removed 
    var $hasAndBelongsToMany = array(
     'Parent' => array(
      'className' => 'Naviitem', 
      'joinTable' => 'naviitems_parents', 
      'foreignKey' => 'naviitem_id', 
      'associationForeignKey' => 'parent_id', 
      'unique' => true, 
      'conditions' => '', 
      'fields' => '', 
      'order' => '', 
      'limit' => '', 
      'offset' => '', 
      'finderQuery' => '', 
      'deleteQuery' => '', 
      'insertQuery' => '' 
     ) 
    ); 
} 
?> 

我用蛋糕烘烤殼產生的控制器和視圖。現在工作正常。感謝您貢獻的所有想法,他們爲我提供了很多幫助。

0

你試圖實現的並不是真正的蛋糕方式。您應該使用兩個表之間的連接表。 Cake的格言是'約定優於配置',所以你應該使用標準的蛋糕方式。

要創建HABTM,您需要三張表。

items 
categories 
categories_items 

項目和類別如您所料。你的連接表應該只包含連接表的兩個ID的如下,

category_id 
item_id 

這將讓你有一個導航項出現在多個類別,你應該選擇這樣做。

更多信息可以在書中找到,http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM

+0

單挑:Ashok沒有兩張桌子,而是一張指向自己的桌子。 :) – pinkgothic 2010-03-25 11:23:19

+0

這是在問題中所要求的'蛋糕的方式':) – 2010-03-25 11:25:16

+0

你誤解了我的問題......我並沒有試圖在類別和項目之間創建HABTM ......我試圖在內部創建一個HABTM分類表。 – Ashok 2010-03-25 11:26:17

2

要擠一個多對多關係(HABTM)爲1:N的關係是不是很好的做法,你會碰到的限制,你不會如果你做得很乾淨,但這是你如何做到的(通用PHP,而不是CakePHP特有的):

你可以在你的表中創建一個列,用逗號分隔的列表存儲所有的父ID。您可以通過讀取各自的ID了......

$ids = explode(',', $idsFromColumn); 

...並把它們寫回使用列...

$idsForColumn = implode(',', $ids); 

實際數據庫的讀寫會發生之前/分別在這些片段之後。


如果要正確做到這一點,你想你主表看起來像這樣:

id (int) - Primary key 
name (varchar) - Name of the Category 

而且你的N:M關係表看起來像這樣:

id (int) - child 
parentid (int) - parent 

你可能會喜歡:

SELECT ... 
FROM 
    main_table AS m 
    [LEFT OUTER|INNER] JOIN 
    relationship_table AS r 
     ON r.id=m.id 
    [LEFT OUTER|INNER] JOIN 
    main_table AS n 
     ON r.parentid=n.id 
WHERE ... 

正是你想要你在哪裏和你的選擇將取決於你希望實現的。至於是否要LEFT OUTER JOININNER JOIN,這取決於您是否要返回m。*中沒有您的relationship_table中的條目的類別(=沒有任何父代)。如果您剛加入語法,請參閱this Wiki article on joins

+0

謝謝,這很有幫助。 – Ashok 2010-03-25 11:29:52

1

這幾乎就是Tree behaviour的設計目的。行爲建立在MPTT (Modified Preorder Tree Traversal)之上。你會因此它配置:

將以下字段添加到您的表:

`parent_id` int(10) unsigned default NULL 
`lft` int(10) unsigned default NULL 
`rght` int(10) unsigned default NULL 

型號:

class Category extends AppModel 
{ 
    var $actsAs = array('Tree'); 
} 

,那麼你會建立一個PARENT_ID <select>到您的類別,修改形式,樹的行爲會照顧其餘的。我想你可以手動處理類別層次結構中的類別的重新排序,但是最好使用在樹狀行爲擴展模型中可用的moveUpmoveDown方法。

這裏也是一個有用的Tree Helper用於將樹列表轉換爲視圖中的有序/無序列表。

+1

嗨,但即使樹行爲不處理多個父子HABTM關係。在你給出的鏈接http://book.cakephp.org/view/91/Tree中,你可以看到每個類別只能是一個子類別。換句話說,每個類別只能有一個父類別。我正在尋找的是每個類別的多個父母...... – Ashok 2010-03-25 13:23:15

+0

Oof,我誤解了你。我很抱歉。 – 2010-03-25 13:28:28

3

希望第二次回答不錯,第一次誤解了這個問題。以下實質上是一個CakePHP實現pinkgothic的答案。

新HABTM聯接表:

CREATE TABLE `categories_parent_categories` (
    `category_id` int(10) unsigned NOT NULL, 
    `parent_category_id` int(10) unsigned default NULL, 
    `order` int(10) unsigned NOT NULL default '0' 
); 

協會型號:

class Category extends AppModel 
{ 
    var $hasAndBelongsToMany = array(
     'ParentCategory' => array(
      'className'    => 'Category', 
      'joinTable'    => 'categories_parent_categories', 
      'foreignKey'   => 'category_id', 
      'associationForeignKey' => 'parent_category_id', 
      'order'     => 'CategoriesParentCategory.order' 
     ) 
    ); 
} 
+0

嗨,謝謝你試圖幫助我,但恐怕代碼沒有工作..蛋糕沒有趕上協會。當添加一個項目時,它沒有顯示選擇一個父ID的選項。 – Ashok 2010-03-29 09:03:53

+0

感謝您輸入Hobonium,我能夠通過對代碼進行一些修改來獲得解決方案。我把它放在這裏。 – Ashok 2010-03-29 12:24:08