1

MySQL에서 closure table을 사용하여 계층 구조를 모델링 할 때 형제 노드의 이름에 대해 고유 제한을 적용하는 방법이 궁금합니다. 나는 어떤 형제가 같은 이름을 가진 없는지 확인하기 위해 spaces 테이블에 고유 제한 조건을 사용하고이 스키마와폐쇄 트리에서 형제 간의 고유 한 이름 제한

create table spaces (
    id int not null, 
    name varchar(50) not null, 
    parent int not null, 
    primary key (id), 
    foreign key (parent) references spaces(id), 
    unique key (name, parent) 
) 

create table space_paths (
    ancestor int not null, 
    descendant int not null, 
    depth int not null, 
    primary key (ancestor, descendant), 
    foreign key (ancestor) references spaces(id), 
    foreign key (descendant) references spaces(id) 
) 

:

내 스키마입니다.

이 접근법의 단점은 space_paths 테이블에 캡슐화 된 계층 구조 메타 데이터를 비정규 화합니다. 그 의미는 space_paths 테이블에있는 경로를 사용하여 spaces 테이블의 parent 필드의 일관성을 수동으로 관리해야한다는 의미입니다.

데이터베이스를 비정규 화하지 않고 형제간에 고유 한 이름 제약 조건을 적용하도록 스키마를 다시 디자인 할 수있는 방법이 있습니까?

+0

비정규 화의 원인에 대해 자세히 설명해 주시겠습니까? 아니면 space_paths 테이블 구조가 이상적이라고 생각하십니까? – wisefish

+0

필자가 언급 한 비정규 화는'space_paths' 테이블이 담당하는 부모 - 자식 관계 정보가'unique key (name, parent)'제약 조건에 의해 중복된다는 사실입니다. 이론적으로 누군가가 테이블에 직접 액세스하거나 앱의 버그를 통해'spaces' 테이블의'parent' 컬럼을'space_paths' 테이블에서 관리되는 것과 다른 부모를 참조하도록 업데이트 할 수 있습니다. 클로저 트리 접근법의 이점이 비용보다 중요한 반면,이 중복을 피하기 위해 형제의 고유성을 강화하는 또 다른 방법이 있는지 궁금합니다. – 0x6e6562

답변

0

클로저 테이블을 사용하는 것이 실제로 여기서 중요한 문제는 아닙니다. UNIQUE KEYparent, name에 입력하면 이미 정의 된 것처럼 보이므로 좋을 것입니다.

슬픔의 원인이 될 수있는 한 가지는 parent 열에 NOT NULL 제한이 있다는 것입니다. "루트"노드를 어떻게 지원할 예정입니까? 루트 노드가 ID 열과 동일한 상위 값을 사용하도록 만들 수 있지만 자체 할당 된 기본 키가 필요합니다 (AFAIK는 삽입 문에서 자동 증가 값을 참조 할 수 없습니다).

INSERT INTO spaces(id, name, parent) values (0, 'root', 0); 
+0

두 개의 열에 고유 한 키를 적용하려는 경우에만 문제를 줄일 수 있는지 잘 모르겠습니다. 동기 부여는 클로저 테이블 접근 방식을 사용하여 트리를 관리하기위한 디자인 결정에서 비롯됩니다. 내 특정 응용 프로그램에서, 또한 주어진 노드 아래에서 형제간에 고유성을 적용해야합니다. 이것은 표준 클로저 테이블 메커니즘에 의해 충족되지 않는 요구 사항입니다. 결국, DB가 당신을 위해하는 좋은 것들이기 때문에, 나는 유일하고 null이 아닌 제약 조건을 사용하게되었습니다. 또한, 내 애플은 이미 눈송이를 사용했기 때문에 자동 증가 키는 문제가되지 않았다. – 0x6e6562