트리 데이터 구조를위한 데이터베이스 구조


151

데이터베이스에서 사용자 정의 가능한 (알 수없는 레벨의 트리 구조) 트리 데이터 구조를 구현하는 가장 좋은 방법은 무엇입니까?

외래 키가있는 테이블을 사용하기 전에이 작업을 한 번 수행했습니다.

어떤 다른 구현을 볼 수 있으며이 구현이 의미가 있습니까?



(2008) SQL Server가 제공 HIERARCHYID 데이터 유형을
BornToCode

답변:


80

가장 일반적으로 구현되는 인접 목록을 언급합니다. https://blogs.msdn.microsoft.com/mvpawardprogram/2012/06/25/hierarchies-convert-adjacency-list-to-nested-sets

구체화 된 경로 및 중첩 세트를 포함한 다른 모델도 있습니다. http://communities.bmc.com/communities/docs/DOC-9902

Joe Celko는이 주제에 관한 책을 썼는데, 이는 일반적인 SQL 관점에서 잘 참조 할 수 있습니다 (위의 중첩 된 세트 기사 링크에서 언급 됨).

또한 Itzik Ben-Gann은 자신의 저서 "Inside Microsoft SQL Server 2005 : T-SQL 쿼리"에서 가장 일반적인 옵션에 대한 개요를 제공합니다.

모델을 선택할 때 고려해야 할 주요 사항은 다음과 같습니다.

1) 구조 변경 빈도-실제 트리 구조는 얼마나 자주 변경됩니까? 일부 모델은 더 나은 구조 업데이트 특성을 제공합니다. 그러나 구조 변경을 다른 데이터 변경과 분리하는 것이 중요합니다. 예를 들어 회사의 조직도를 모델링 할 수 있습니다. 일부 사람들은 직원 ID를 사용하여 직원을 관리자와 연결하는 인접 목록으로이를 모델링합니다. 이것은 일반적으로 차선책입니다. 종종 더 잘 작동하는 접근 방식은 직원 구조와는 별도로 조직 구조를 모델링하고 직원을 구조의 속성으로 유지하는 것입니다. 이런 식으로 직원이 회사를 떠날 때 조직 구조 자체는 변경 될 필요가 없으며, 떠난 직원과의 연결 일뿐입니다.

2) 트리는 쓰기 또는 읽기 중입니다-일부 구조는 구조를 읽을 때 매우 잘 작동하지만 구조에 쓸 때 추가 오버 헤드가 발생합니다.

3) 구조에서 어떤 유형의 정보를 가져와야합니까-일부 구조는 구조에 대한 특정 종류의 정보를 제공하는 데 탁월합니다. 노드 및 모든 하위 노드 찾기, 노드 및 모든 상위 노드 찾기, 특정 조건을 충족하는 하위 노드 수 찾기 등이 여기에 포함됩니다. 가장 적합한 구조를 결정하려면 구조에서 어떤 정보가 필요한지 알아야합니다. 너의 요구.


안녕하세요, 나는 질문에 언급 된 것과 똑같은 문제에 직면하고 있으며 위의 주제에 대해 질문하고 싶습니다. 첫 번째 주제 (같은 테이블에서 ParentId가 참조 된 조직 구조화 테이블 (직원 구조화되지 않음))와 같은 구조를 고려할 때 특정 영역의 보스를 누가 설정해야합니다. 해당 지역의 모든 직원을 직접 지정합니다. 특정 지역의 보스를 어디에 두시겠습니까? 같은 지역이나 한 덩어리 위에? 내 접근 방식은 위의 그룹을 참조하는 것이므로 더 나은 구조를 생각할 수 있습니다. 감사.
Marcos Buarque

1
첫 번째 링크가 끊어진 것 같습니다.
Jorge Leitao

훌륭한 답변입니다. 감사합니다 @JeremyDWill!
bobocopy

56

MySQL에서 계층 적 데이터 관리를 살펴보십시오 . 관계형 데이터베이스에 계층 적 (트리 형) 데이터를 저장하고 관리하기위한 두 가지 접근 방식에 대해 설명합니다.

첫 번째 방법은 인접 목록 모델이며, 이는 테이블 자체를 참조하는 외래 키를 갖는 본질적으로 설명하는 것입니다. 이 방법은 간단하지만 전체 트리 작성과 같은 특정 쿼리에는 매우 비효율적 일 수 있습니다.

이 기사에서 논의 된 두 번째 접근법은 중첩 세트 모델입니다. 이 접근 방식은 훨씬 더 효율적이고 유연합니다. 자세한 설명 및 예제 쿼리는 기사를 참조하십시오.


귀하의 링크에는 매우 흥미로운 주제가 논의되고 있습니다. 감사!
프리츠

9

관계형 데이터베이스를 사용하여 트리 데이터 구조를 구성해야하는 경우 Postgresql에는 계층 구조 트리 구조에 저장된 데이터 레이블을 나타내는 데이터 유형을 제공하는 멋진 ltree 모듈이 있습니다. 거기에서 아이디어를 얻을 수 있습니다 (자세한 내용은 http://www.postgresql.org/docs/9.0/static/ltree.html 참조 )

일반적으로 LDAP는 레코드를 계층 구조로 구성하는 데 사용됩니다.


2

외래 키가있는 테이블을 갖는 것은 나에게 의미가 있습니다.

그런 다음 SQL에서 공통 테이블 표현식을 사용하거나 Oracle에서 connect by prior 문을 사용하여 트리를 작성할 수 있습니다.


LogID ID 열이있는 로그 테이블과 LogID 열을 가리키는 FK가있는 ParentLogID 열이 있습니다. 트랜잭션의 첫 번째 로그 행이 작성되면 SCOPE_IDENTITY ()를 가져옵니다. 다른 모든 로그 레코드는 ParentLogID 열에이 값으로 기록됩니다. 이것은 함께 속한 행을 그룹화하는 데 실제로 유용합니다. 이것이없이 무슨 일이 일어 났는지 알 수있는 유일한 방법입니다. 여러 트랜잭션에서 모두 로그 행이 혼동 될 수 있습니다.
KM.

@KM-그는 "말이되지 않는다"는 말이 아니라 "말이된다"
John Rasch



당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.