2010-03-25 1 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 join table을 사용합니다.

범주 내에서 HABTM이 필요한 경우 어떻게해야합니까?

+0

u는 쉼표 나 인터넷 검색을하는 동안 –

+0

한 흥미로운 질문이 :-) – richsage

+0

내가 이것을 발견 된 일부 구분자, http://n2.nabble.com/Saving-self-로 구분 그들에 의해 하나 개의 필드에 여러 값을 저장할 수 있습니다 referential-HABTM-relationships-td1126141.html, 나는 똑같이 복제하려했지만 Cake는 연관성을 잡지 못하고있다. 어떤 생각, 누군가? – Ashok

답변

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의 맥심은 '컨벤션 오버 컨벤션 (convention over configuration)'이므로 표준 케이크 방식을 사용해야합니다.

HABTM을 만들려면 세 개의 테이블이 필요합니다.

항목 및 카테고리는 예상대로입니다. 다음과 같이 조인 테이블은 당신이 이렇게 선택해야, 이것은 당신이 하나의 탐색 항목에 여러 범주에 표시해야 할 수 있습니다

category_id 
item_id 

, 조인 된 테이블의 두 아이디의를 포함해야합니다.

더 많은 정보는이 책에서 찾을 수 있습니다 , http://book.cakephp.org/view/1044/hasAndBelongsToMany-HABTM

+0

헤드 업 : 아쇽은 두 개의 테이블이 아니라 하나의 테이블을 참조합니다. :) – pinkgothic

+0

이것은 질문에서 요청한대로 '케이크 방법'입니다. –

+0

내 질문에 대해 오해했습니다 ... 카테고리와 항목간에 HABTM을 만들려고하지 않습니다 ... 내에서 HABTM을 만들려고합니다. 카테고리 테이블. – Ashok

2

의 n 짜려고 : 1로 m 관계 (HABTM을) : N 관계가없는 것이 좋습니다 당신이 한계에 실행하겠습니다 당신은 않을 것 (CakePHP가 아닌 일반 PHP) :

모든 부모 ID를 쉼표로 구분 된 목록에 저장하도록 테이블에 열을 만들 수 있습니다. 당신은 데이터베이스의

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

실제 읽기 - 쓰기 전에 일어날 것 ... ... 사용하여

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

을 개별 ID를 읽어 ... 다시 사용하여 열에을 쓸 수 있습니다/그 발췌문 다음에 각각.

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 JOIN 또는 INNER JOIN, 그것은 relationship_table (= 부모 없음) 항목이없는 m. * 카테고리를 반환할지 여부에 따라 다릅니다. 새로운 구문에 참여하려면 this Wiki article on joins을 살펴보십시오.

+0

감사합니다. 도움이되었습니다. – Ashok

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 

모델 : : 당신은 다음의 카테고리-수정 양식에 PARENT_ID <select>을 구축 할 것

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

이 테이블에 다음 필드를 추가 Tree 동작은 나머지를 처리합니다. 범주 계층의 계층에서 범주 순서를 수동으로 처리 할 수는 있지만 트리 동작으로 확장 된 모델에서 사용할 수있는 moveUpmoveDown 메서드를 사용하는 것이 좋습니다.

여기에서 트리 목록을 정렬 된/정렬되지 않은 목록으로 변환하는 데 유용한 Tree Helper도 있습니다.

+1

안녕하세요,하지만 Tree 동작조차도 여러 개의 상위 하위 하위 HABTM 관계를 처리하지 않습니다. http://book.cakephp.org/view/91/Tree 링크에서 각 카테고리는 한 번만 하위 카테고리가 될 수 있습니다. 즉, 각 카테고리는 단 하나의 상위 카테고리 만 가질 수 있습니다. 내가 찾고있는 것은 각 카테고리에 대한 복수 부모님입니다 ... – Ashok

+0

Oof, 나는 당신을 잘못 읽었습니다. 내 사과. –

3

처음으로 질문을 오해하고 두 번째 대답에 나쁜 형식이 아니길 바랍니다. 다음은 본질적으로 핑크 고딕의 답을 CakePHP로 구현 한 것입니다. 모델

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' 
); 

협회 :

새로운 HABTM 테이블에 가입

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

안녕하세요, 도와 주셔서 고맙습니다.하지만 코드가 작동하지 않는 것이 두렵습니다. Cake는 연관성을 파악하지 못했습니다. 항목을 추가 할 때 상위 ID를 선택하는 옵션이 표시되지 않습니다 .. – Ashok

+0

입력 Hobonium을 주셔서 감사합니다. 귀하의 코드에서 일부 수정을 통해 솔루션을 얻을 수있었습니다. 나는 그것을 여기에 게시했다. – Ashok