문제

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 나는 이것이 "약간 지나친" 일이라는 것을 알고 있지만 재미로 이 일을 하고 있습니다(재미:동사, 그것을 함으로써 불가능을 찾는 것.:-)

도움이 되었습니까?

해결책

당신이 겪고있는 문제는 분명하고 SQL의 재귀입니다.부모의 부모를 구해야합니다 ...리프의 전체 내용을 업데이트합니다(이전 항목을 빼고 새 항목을 추가하거나 다시 계산).트리의 구조를 확인하고 모든 하위 노드와 업데이트할 리프의 상위/경로 목록을 가져오려면 어떤 형태의 식별자가 필요합니다.

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

한 페이지를 살펴보도록 하겠습니다 mysql에서 이 방법을 사용하면 이 방법이 마음에 들지 않을 경우를 대비해 이 토론을 계속하지 마세요.하지만 마음에 드신다면 게시/수정해 주세요. 시간이 좀 걸리고 명확하게 설명하겠습니다.

다른 팁

귀하의 질문을 올바르게 이해했는지 잘 모르겠지만 이것이 효과가 있을 수 있습니다. SQL의 트리에 대한 나의 견해.

링크된 게시물에서는 데이터베이스(이 경우 PostgreSQL)에 트리를 저장하는 방법을 설명했지만 이 방법은 충분히 명확하므로 모든 데이터베이스에 쉽게 채택할 수 있습니다.

이 방법을 사용하면 수정된 노드에 따라 모든 노드를 쉽게 업데이트할 수 있습니다. 케이N 간단한 SELECT 쿼리 N 의 거리이다 케이 루트 노드에서.

당신의 나무가 정말 깊지 않기를 바랍니다 :).

행운을 빌어요!

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top