2008-08-21 2 views
1

나는 MySQL 데이터베이스에서 에지로 엔코 드 된 트리를 가지고있다.MySQL 데이터베이스에서 재귀 불변성을 유지하는 방법?

CREATE TABLE items (
    num INT, 
    tot INT, 
    PRIMARY KEY (num) 
    ); 
CREATE TABLE tree (
    orig INT, 
    term INT 
    FOREIGN KEY (orig,term) REFERENCES items (num,num) 
    ) 

트리의 각 리프에 대해 items.tot은 누군가에 의해 설정된다. 내부 노드의 경우 items.tot은 자식 노드의 합계가되어야합니다. 반복적으로 다음 쿼리를 실행하면 원하는 결과가 생성됩니다.

UPDATE items SET tot = (
    SELECT SUM(b.tot) FROM 
     tree JOIN items AS b 
     ON tree.term = b.num 
     WHERE tree.orig=items.num) 
    WHERE EXISTS 
     (SELECT * FROM tree WHERE orig=items.num) 

(실제로는 작동하지 않지만 점 옆에 있습니다.)

데이터베이스가 존재하고 불변성이 이미 충족되었다고 가정하십시오.

질문 :

이 요구 사항을 유지하면서 DB를 업데이트하는 가장 유용한 방법은 무엇입니까? 업데이트를 통해 노드를 이동하거나 리프 노드의 tot 값을 변경할 수 있습니다. 리프 노드는 리프 노드로 유지되고 내부 노드는 내부 노드로 유지되며 모든 것이 적절한 트리로 유지된다고 가정 할 수 있습니다.

내가 가지고있는 몇 가지 생각 :

  • 모든 업데이트 후 전체 무효화, 모든 것을 다시 계산 (음 ... 아니오)
  • 부모를 업데이트하기 위해 항목 테이블에 트리거 설정 업데이트 된 행
    • 이것은 재귀 적입니다 (트리거 업데이트, 트리거 업데이트 등을 업데이트합니다 ...).
    • 작동하지 않습니다. MySQL이 트리거를 시작한 테이블을 업데이트 할 수 없습니다.
  • 업데이트 된 모든 행의 상위 업데이트를 예약하도록 트리거를 설정합니다.
    • 반복적입니다 (일정에서 항목을 가져 와서 더 많은 항목을 처리합니다).
    • 이 기능은 무엇부터 시작합니까? 클라이언트 코드를 신뢰할 수 있습니까?
    • 장점은 업데이트가 올바르게 주문 된 경우 합계가 컴퓨터 여야한다는 것입니다. 그러나 그 순서는 그것이 자신의 합병증입니다.

이상적인 솔루션은 다른 "집계 불변성"으로 일반화됩니다.

FWIW 나는 이것이 "약간 배제되어"있는 것을 알고 있지만, 재미로 이것을하고 있습니다. (재미 : 동사, 불가능 해. :-)

답변

1

문제는 현재 SQL에서 재귀입니다. 잎의 부모의 부모를 가져와 합계를 업데이트해야합니다 (낡은 것을 빼고 새 것을 추가하거나 다시 계산). 트리의 구조를보기 위해서는 어떤 형태의 식별자가 필요하며, 모든 노드 노드와 업데이트 할 리프의 부모/경로 목록을 가져와야합니다.

이 방법은 일정한 공백 (테이블에 2 개의 열을 추가합니다. 그러나 하나의 테이블 만 필요합니다. 그렇지 않으면 나중에 조인을 할 수 있습니다). 나는 잠시 전 선주문 및 순차 순회에 의해 계산 된 '왼쪽'및 '오른쪽'열 (분명히 그 이름이 아님)을 사용하여 계층 적 형식을 사용하는 구조로 놀았습니다. 걱정하지 마십시오. 이들은 매번 다시 계산할 필요가 없습니다.

답변으로이 방법을 사용하지 않으려는 경우에 대비하여이 토론을 계속하는 대신 페이지 using this method in mysql을 살펴 보겠습니다. 그러나 당신이 그것을 좋아한다면, 게시/편집하고 나는 약간의 시간이 걸리고 명확하게 할 것입니다.

+0

흥미로운 접근 방법입니다. 내가 좋아하지 않는 것은'N * Log (N)'공간과 같은 것을 사용한다는 것입니다. 또한 주요 mods를 요구하는 몇 가지 버전 제약이 있습니다. - 슬프게도 저자는 집계 값을 업데이트하는 방법에 결코 관여하지 않습니다. 몇 가지 접근법을 생각할 수 있지만 구현에 의존 할 것입니다. - 이걸 좀 더 생각해야 해. ([아주 오래된] 대답에서 옮겼습니다.) – BCS

+0

형식을 언급하는 mysql 문서에 대한 링크를 업데이트했습니다. – nlucaroni

1

나는 당신의 질문을 올바르게 이해하고 있는지 모르지만, 이것은 My take on trees in SQL 일을 할 수있다.

링크 된 게시물은 데이터베이스에 트리를 저장하는 방법을 설명합니다 (이 경우 PostgreSQL). 그러나이 방법은 충분히 명확하므로 어떤 데이터베이스에도 쉽게 적용 할 수 있습니다.N 루트 노드에서 K의 거리를 모든 노드에 대한 N 간단한에 select 쿼리로 수정 노드 K에 따라 당신은 쉽게 업데이트 할 수 있습니다이 방법

.

나는 나무가 정말로 깊지 않기를 바래. :).

행운을 빌어 요!

관련 문제