MySQL&PHP - 创建多个父子关系

问题描述:

我试图建立一个使用具有层次结构的类别表的导航系统。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

明白了最后。

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' => '' 
     ) 
    ); 
} 
?> 

我用蛋糕烘烤壳产生的控制器和视图。现在工作正常。感谢您贡献的所有想法,他们为我提供了很多帮助。

你试图实现的并不是真正的蛋糕方式。您应该使用两个表之间的连接表。 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

要挤一个多对多关系(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

这几乎就是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

希望第二次回答不错,第一次误解了这个问题。以下实质上是一个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

您可以使用递归构建父/子无限树。 更多信息可在以下网址找到。 Get Unlimited parent and child tree in php