2016-09-27 2 views
0

PHP/MySQL의 클로저 테이블을 사용하여 특히 Codeigniter를 사용하여 건물을 짓고있는 어플리케이션에 대해 머리를 쓰려고합니다. 각 영역에는 여러 개의 영역이있을 수 있습니다. 위치, 부서 등PHP/MySQL을 사용하여 클로저 테이블에 삽입하기

나는 어떻게 작동 하는지를 알기 위해 http://www.slideshare.net/billkarwin/models-for-hierarchical-data을 사용했다.

나는 데이터를 액세스하는 데 도움이되도록 https://gist.github.com/dazld/2174233을 사용하고 있습니다. 데이터를 액세스 할 수 있도록 도와 주며, 필요한만큼 데이터를 가져 오는 방법을 적용했습니다. 이는 모두 좋습니다.

하지만 이제 데이터를 삽입하려고하는데 주변을 둘러 볼 수 없습니다. 그래서 위의 스크립트에서 추가 방법을 적용했지만, 나는 그것을 이해하지 않고, 나는 그것이 지역 테이블을 Heres

+------------+-------------+------+-----+---------+----------------+ 
| Field  | Type  | Null | Key | Default | Extra   | 
+------------+-------------+------+-----+---------+----------------+ 
| area_id | int(11)  | NO | PRI | NULL | auto_increment | 
| area_title | varchar(40) | NO |  | NULL |    | 
| area_name | varchar(40) | NO |  | NULL |    | 
| org_id  | int(11)  | NO |  | NULL |    | 
+------------+-------------+------+-----+---------+----------------+ 

에게 Heres는

area_hierarchy 테이블을 동작하지 않습니다

무슨 일이 $입니다, 그래서 특별히

public function add($node_id, $target_id) { 

    $sql = 'SELECT ancestor, '.$node_id.', lvl+1 
      FROM area_hierarchy 
      WHERE descendant = '.$target_id.' 
      UNION 
      SELECT '.$node_id.','.$node_id.',0'; 

    $query = 'INSERT INTO area_hierarchy (ancestor, descendant,lvl) ('.$sql.')'; 

    $result = $this->db->query($query); 

    return $result; 

} 

:

+------------+---------+------+-----+---------+----------------+ 
| Field  | Type | Null | Key | Default | Extra   | 
+------------+---------+------+-----+---------+----------------+ 
| id   | int(11) | NO | PRI | NULL | auto_increment | 
| ancestor | int(11) | NO |  | NULL |    | 
| descendant | int(11) | NO |  | NULL |    | 
| lvl  | int(11) | NO |  | NULL |    | 
+------------+---------+------+-----+---------+----------------+ 
는 Heres는 방법 나는 항목을 추가하는 데 사용하려고 해요 node_id 및 $ target_id.

lvl + 1은 무엇입니까?

그래서 새로운 최상위 영역을 추가하면이 데이터에는 어떤 데이터가 전달됩니까?

질의는 실패하고 area 테이블에서 area_id 열의 값 것이다 UNION

+1

노드 ID는 추가 할 새 노드 (하위)이며 대상 ID는 상위 (상위) 노드입니다. 노동 조합은 자기 기준을 다루어야한다. 자기 기준은 언제나 종결되어야한다. B 아래에 D를 추가하려면 B의 모든 조상을 선택하고 D에 대한 관계를 만들어야합니다. 또한 D = D에 대해 자체 수준을 0으로 설정해야합니다. –

+1

예를 들어, 10 개의 영역, 1,2,3,4,5가 있고 이들이 동일한 기본 키를 가지고 있다고 가정 해보십시오. 그들은 모두 루트 레벨에 존재해야하며, 먼저 그 영역을 추가하면, 각 노드에 대해'add ($ areaId) '를 호출합니다. 그런 다음 6,7,8이 3의 자식이되기를 원합니다. 그런 다음 각 영역에 대해 add ($ areaId, 3)를 호출합니다. 마지막으로, 9와 10이 8의 자식이되기를 원합니다. 우리는'add ($ areaId, 8)'를 호출합니다. 쿼리가 실패하거나 예상대로 작동하지 않는 이유에 대한 도움이 필요한 경우 오류 및 예상 결과를 제공해야합니다. –

+0

감사합니다. 좋은 설명입니다. 나는 멀리 가서 실험을한다. – frobak

답변

1

$node_id 후 구문 오류 준다. 아마도 그것은 지역 표에 방금 추가 한 행입니다.

$target_idarea 테이블의 다른 행에있는 area_id 열의 값이됩니다.이 열은 "부모"로 식별되는 행인 직접 조상입니다.

lvl+1은 계층 구조의 생성 또는 수준이며 ... 하위 항목이 부모로부터 얼마나 멀리 떨어져 있는지를 나타냅니다.

"최상위"영역을 새로 추가하는 경우 에 $node_id을 사용합니다.

이것을 이해하는 가장 좋은 방법 중 하나는 area_hierarchy 테이블의 "현재 상태"와 노드가 추가 될 때 테이블의 "끝 상태"가 무엇인지 확인하는 것입니다.아이로, = 22 area_id,

ancestor descendant lvl 
-------- ---------- --- 
11  11   0 

을 우리는 지역 테이블에 다른 행을 추가하는 경우 : 트리에서 단지 최상위 노드와

은 = 11 area_hierarchy 테이블과 같을 것이다 area_id area_id = 11 (직계 후손은) 우리가 area_hierarchy이 두 행을 추가해야합니다 area_id = 22의 자식으로, 333 = area_id,

ancestor descendant lvl 
-------- ---------- --- 
11  22   1 
22  22   0 

우리는 지역 테이블에 다른 행을 추가 할 경우, 우리는 필요 다음 행을 area_hierarchy 테이블에 추가하십시오.

ancestor descendant lvl 
-------- ---------- --- 
11  333  2 
22  333  1 
333  333  0 

추가해야하는 첫 번째 두 행은 테이블에 이미있는 행 (descendant = 22)과 매우 흡사합니다. 차이점은 새 행의 자손은 22 대신 333이며 lvl의 값은 테이블에 이미있는 행의 값보다 하나 많다는 것입니다.

우리가 추가해야 할 세 번째 행은 자체에 대한 참조입니다. 우리가 area_id = 11을 그 자체의 "부모"로 생각한 것처럼.

UNION 이후의 세 번째 행입니다. 이미 area_hierarchy에있는 행을 복사하여 하위 열의 값을 추가 할 노드의 ID (333)로 바꾸고 lvl을 1 늘리면 얻을 수있는 첫 번째 두 행.

일단 어떤 행 추가 할 필요가 있고 테이블의 다른 행을 복사/수정하여 파생시킬 수 있다면 SQL이 이해되기 시작합니다.


당신은 area_id = (333)에 대해 그 세 행을 추가하는 추가 기능을 호출 달성 할

: 계층 구조에서 새로운 "최상위 수준"으로 = 4444을 area_id 추가하려면

add(333,22); 

를 :

add(4444,4444); 
+0

감사합니다. 매우 유익하고 명확합니다. 이제 클로저 테이블에 칼럼으로 색인을 붙여야 하나 이상의 질문이 생깁니다. ID는 조직의 ID입니까? – frobak

+0

@frobak : 예, 적절한 인덱스를 추가하십시오. 인덱스는 몇 가지 중요한 목적을 제공합니다. 인덱스의 경우 고유 한 제약 조건을 적용하는 데 사용할 수 있습니다. 데이터베이스에 중복 행이 테이블에 추가되지 않도록하려면 고유 제한 조건을 추가하십시오. 예를 들어, 두 번째 호출'add (4444,4444)'를 실행하는 것을 고려하십시오. 데이터베이스에서 원하는 최종 상태는 무엇입니까? area_hierarchy 테이블에 두 개의 동일한 * 행이 필요합니까? 인덱스의 다른 목적은 성능을 향상시키는 것입니다.가장 적합한 색인은 명령문이 실행될 명령문에 따라 다릅니다. – spencer7593

관련 문제