B 트리와 B + 트리의 차이점은 무엇입니까?


293

A의 B-나무 는 모두 저장할 수있는 내부 및 잎 노드의 키와 데이터를 하지만,에 ㄱ + 트리 당신은에 데이터를 저장해야 할 경우에만 리프 노드 .

b + 트리에서 위의 작업을 수행하면 이점이 있습니까?

직관적으로 훨씬 빠르기 때문에 어디에서나 b + 트리 대신 b- 트리를 사용하지 않겠습니까?

b + 트리에서 키 (데이터)를 복제해야하는 이유는 무엇입니까?


37
그들이 말하는 것은 "B-Tree"대 B + -Tree입니다. 빼기 부호가 아닌 하이픈을 의미합니다.
stu

답변:


421

아래 이미지는 B + 트리와 B 트리의 차이점을 보여줍니다.

B + 나무의 장점 :

  • B + 트리에는 내부 노드와 관련된 데이터가 없으므로 메모리 페이지에 더 많은 키를 넣을 수 있습니다. 따라서 리프 노드에있는 데이터에 액세스하려면 캐시 누락이 덜 필요합니다.
  • B + 트리의 리프 노드는 연결되어 있으므로 트리의 모든 객체를 전체 스캔하려면 모든 리프 노드를 통해 하나의 선형 패스 만 있으면됩니다. 반면에 AB 트리는 트리의 모든 레벨을 순회해야합니다. 이 전체 트리 순회에는 B + 리프의 선형 순회보다 더 많은 캐시 누락이 포함될 수 있습니다.

B 나무의 장점 :

  • B 트리에는 각 키가있는 데이터가 포함되어 있으므로 자주 액세스하는 노드가 루트에 더 가까이있을 수 있으므로 더 빠르게 액세스 할 수 있습니다.

B와 B + 나무


2
리프 노드의 항목 수에 대한 제약이 있습니까?
TLE

38
@TLE 좋은 질문입니다! 예. 하드 드라이브는 한 번에 최소 메모리 페이지에 액세스하므로 모든 포인터를 단일 메모리 페이지에 맞추려고합니다. 리프 액세스 당 하나의 디스크 읽기만 필요하므로 리프에 페이지 크기 이상의 포인터를 할당하지 않습니다. 페이지 크기의 포인터로 리프를 채운 다음이 리프에 다른 포인터를 추가하려는 경우이 노드의 자식 두 개를 만들고 각 새 자식에 대한 나뭇잎 포인터의 절반을 제공합니다. 물론 나무의 높이를 최소로 유지하기 위해 약간의 전환이있을 수 있습니다. 도움이 되나요?
로즈 PERRONE

B- 트리의 각 리프 노드의 마지막 포인터는 다음 리프 노드를 가리켜 야합니다.
camino

8
오래된 스레드를 부딪 히게해서 미안하지만, camino의 의견이 어떻게 정확한지에 대한 @Babyburger의 의견은 실제로 사실이 아닙니다. 실제로 B- 트리는 리프 노드를 연결하지 않았습니다. B +입니다.
Jason

탁월한 답변에 감사드립니다. 데이터베이스 컨텍스트의 B / B + 트리에서 개체 전체를 스캔해야하는 유스 케이스는 무엇입니까? 주로 인덱싱에 사용되기 때문에 검색은 전체 트리를 거의 스캔하지 않고 인덱스 경로를 통과해야합니다. 맞습니까?
Siddhartha

113

B 트리보다 B + 트리의 주요 장점은 데이터에 대한 포인터를 제거하여 팬 아웃을 높이고 트리 깊이를 잠재적으로 줄임으로써 다른 노드에 대한 더 많은 포인터를 넣을 수 있다는 것입니다.

단점은 내부 노드에서 일치하는 것을 발견했을 때 초기 결과가 없다는 것입니다. 그러나 두 데이터 구조 모두 팬 아웃이 많으므로 대부분의 일치 항목이 리프 노드에 배치되어 평균 B + 트리가 더 효율적입니다.


1
나는 전체 스캔을 할 때 효율성의 차이를 강조하기 때문에 Jeff의 대답을 선호합니다.
로즈 Perrone

순차 순회를 사용하여 b- 트리를 순회하면 모든 값을 O (n) 시간으로 정렬 된 순서대로 읽으므로 혼란 스럽습니다. 각 트리 노드가 실제 페이지 크기에 맞게 크기가 조정되면 더 이상 최적의 상태가 아닌 것처럼 보입니다. 반대로, b + tree에서 첫 번째 (가장 작은) 값을 얻는 데 드는 비용은 O (log n)이고 모든 리프를 통과하는 데 드는 비용은 O (n)이므로 총 비용은 O (log n + n)입니다. 이것은 더 많은 작업과 더 많은 디스크 읽기이며, 트리에는이 모든 추가 데이터가 있기 때문에 의미가 있습니다. 나는 그것을 얻지 못한다.
Eric

위 문장에서 '팬 아웃'의 또 다른 단어는 무엇입니까?
Jorge Bucaran

3
@JorgeBucaran fanout = 노드에서 나오는 가장자리 수
bantmen

33

터미널 노드가 연결된 목록을 형성하기 때문에 트리가 인덱싱하는 모든 데이터를 살펴 보듯이 B + 트리는 전체 스캔을 수행하는 것이 훨씬 쉽고 성능이 뛰어납니다. B-Tree로 전체 스캔을 수행하려면 모든 데이터를 찾기 위해 전체 트리 순회를 수행해야합니다.

반면에 B- 트리는 트리가 RAM 또는 다른 비 블록 스토리지에 상주 할 때 키를 사용하여 특정 데이터를 찾는 경우 더 빠를 수 있습니다. 트리에서 일반적으로 사용되는 노드를 올릴 수 있으므로 데이터를 얻는 데 필요한 비교가 적습니다.


1
그렇다면 모든 데이터에서 순차적으로 읽혀서 잎을 가로 질러 갈 수있는 상황에 B + 트리가 사용될 것이라는 데 동의하십니까? B 트리는 랜덤 액세스 상황에 이상적인 반면?
JDPeckham

31
  1. B 트리에서 검색 키와 데이터는 내부 또는 리프 노드에 저장됩니다. 그러나 B + 트리에서 데이터는 리프 노드에만 저장됩니다.
  2. 모든 데이터가 리프 노드에서 발견되므로 B + 트리의 전체 스캔이 매우 쉽습니다. B 트리의 전체 스캔에는 전체 순회가 필요합니다.
  3. B 트리에서 데이터는 리프 노드 또는 내부 노드에서 찾을 수 있습니다. 내부 노드 삭제는 매우 복잡합니다. B + 트리에서 데이터는 리프 노드에서만 발견됩니다. 리프 노드 삭제가 쉽습니다.
  4. B 트리에서의 삽입은 B + 트리보다 복잡합니다.
  5. B + 트리는 중복 검색 키를 저장하지만 B 트리는 중복 값이 ​​없습니다.
  6. B + 트리에서 리프 노드 데이터는 순차적 링크리스트로 정렬되지만 B 트리에서 리프 노드는 링크 된리스트를 사용하여 저장할 수 없습니다. 많은 데이터베이스 시스템의 구현에서는 B + 트리의 구조적 단순성을 선호합니다.

15

데이터베이스 시스템 개념의 예 5

B + 트리 B + 트리

해당 B- 트리 브 트리


5
나는 B-Tree가 노드의 아이들과 연결되어 있다고 생각하지 않습니다. 예를 들어 양식 Clearview bucket받는 사람을 Mianus Bucket. 어쨌든 두 Downtown bucket트리 사이에서 B- 트리에서 인덱스 스캔을 수행하려는 경우 검색 대상이 많으므로 역 추적이 필요 하기 때문에 그렇게하는 것은 의미가 없습니다 . 이거 어디서 났어?
Evan Carroll

1
@EvanCarroll 데이터베이스 시스템 개념 5 일, 아마도 저자와 확인을 할 필요가있다 :)
camino

11

"훨씬 빨리"정의하십시오. 무의식적으로 그들은 거의 같습니다. 차이점은 이들이 보조 스토리지를 사용하는 방법에 있습니다. B- 트리B + 트리 에 대한 Wikipedia 기사는 매우 신뢰할 수 있습니다.


2
찰리에 동의합니다. B-Tree의 한 노드는 하나의 보조 메모리 페이지 또는 블록을 나타내므로 한 노드에서 다른 노드로의 통과에는 시간 소모적 인 페이지 변경이 필요합니다.

11

Adegoke A, Amit

사람들이 누락 한 중요한 점은이 섹션에서 설명한 데이터와 포인터의 차이점이라고 생각합니다.

포인터 : 다른 노드를 가리키는 포인터.

데이터 :-데이터베이스 인덱스의 맥락에서 데이터는 다른 곳에 존재하는 실제 데이터 (행)에 대한 또 다른 포인터 일뿐입니다.

따라서 B 트리의 경우 각 노드에는 세 개의 정보 키, 키와 관련된 데이터에 대한 포인터 및 자식 노드에 대한 포인터가 있습니다.

B + 트리에서 내부 노드는 하위 노드에 대한 키와 포인터를 유지하고 리프 노드는 관련 데이터에 대한 키와 포인터를 유지합니다. 이것은 주어진 크기의 노드에 대해 더 많은 키를 허용합니다. 노드의 크기는 주로 블록 크기에 의해 결정됩니다.

노드 당 더 많은 키를 갖는 장점은 위에 설명되어 있으므로 입력 노력을 절약 할 수 있습니다.


10

B + 트리는 블록 기반 스토리지 (예 : 하드 디스크)에서 특히 좋습니다. 이것을 염두에두고, 예를 들어 (내 머리 꼭대기에서) 몇 가지 이점이 있습니다.

  • 높은 팬 아웃 / 낮은 깊이 : 즉, 데이터를 얻기 위해 더 적은 블록을 가져와야합니다. 포인터와 데이터가 혼합 된 경우 각 읽기마다 포인터가 줄어들므로 데이터를 찾으려면 더 많은 검색이 필요합니다

  • 간단하고 일관된 블록 스토리지 : 내부 노드에는 N 개의 포인터가 있고, 리프 노드에는 데이터가 있으며, 아무것도 없습니다. 구문 분석, 디버그 및 재구성이 쉬워집니다.

  • 높은 키 밀도는 최상위 노드가 거의 확실히 캐시에 있음을 의미하며 많은 경우 모든 내부 노드가 빠르게 캐시되므로 데이터 액세스 만 디스크로 이동해야합니다.


2
주로 인 메모리 트리에 사용됩니다. 그러나 빨강 검정 나무, 건너 뛰기 목록 등과 같은 다른 인기있는 옵션이 있습니다.
Javier

B- 트리는 또한 효율적인 블록 기반 스토리지를 위해 설계되어 점근 적 수의 노드 액세스를 제한합니다. 그렇지 않으면, 랜덤 액세스로 메모리와 같은 저장 매체를 사용하는 경우 더 나은 결과를 얻기 위해 레드-블랙 트리와 같은 자체 균형 이진 트리를 사용할 수 있습니다.
dionyziz 2013

당신의 첫 번째 요점은 "더 많은 추구"보다는 "더 적은 탐색"이라고 말해서는 안됩니다. 작은 깊이-> 적은 탐색
Jesse

1
@Jesse : high fanout => low depth => 덜 탐색하지만 데이터와 포인터를 혼합하면 더 적은 포인터를 의미합니다 => low fanout => 더 깊이 => 더 많은 탐색
Javier

1
@AdegokeA : B + 트리에는 두 종류의 노드가 있습니다 : 키와 포인터 만 있고 데이터는없는 내부 노드; 데이터와 포인터가없는 리프 노드. 각 내부 노드에서 최대 키 수를 허용합니다. 내부 노드에 데이터를 저장하면 더 적은 포인터를 맞출 수 있고 나무가 커집니다.
Javier

5

B + 트리에서는 포인터 만 내부 노드에 저장되므로 크기가 B 트리의 내부 노드 (데이터 + 키 모두 저장)보다 크게 작아집니다. 따라서 B + 트리의 인덱스는 단일 디스크 읽기로 외부 저장소에서 가져 와서 대상 위치를 찾기 위해 처리 할 수 ​​있습니다. B 트리 인 경우, 모든 의사 결정 프로세스마다 디스크 읽기가 필요합니다. 내 요점을 분명히 밝히기를 바랍니다! :)


4

2

예를 들어 행당 데이터가 많은 테이블이 있습니다. 즉, 객체의 모든 인스턴스가 크다는 것을 의미합니다.

여기서 B 트리를 사용하는 경우 대부분의 시간은 데이터가 포함 된 페이지를 스캔하는 데 소비됩니다. 데이터베이스에서 B + 트리를 사용하여 오브젝트 데이터 스캔을 피하는 이유입니다.

B + 트리는 데이터와 키를 분리합니다.

그러나 데이터 크기가 작 으면 B 트리가하는 키로 저장할 수 있습니다.


1
"여기에서 B 트리를 사용하는 경우 데이터가있는 페이지를 스캔하는 데 대부분의 시간이 소요됩니다"-필요하지 않습니다. B- 트리 노드는 데이터 자체가 아닌 디스크의 데이터에 대한 "포인터"만 유지할 수 있습니다.
TT_

2

B- 트리와 B + 트리의 주요 차이점은 B- 트리가 검색 키 값의 중복 저장을 제거한다는 것입니다 .B- 트리에서 검색 키가 반복되지 않으므로 더 적은 수의 트리 노드를 사용하여 인덱스를 저장할 수 없습니다 그러나 리프가 아닌 노드에 나타나는 검색 키가 B- 트리의 다른 곳에 나타나지 않으므로 리프가 아닌 노드의 각 검색 키에 대한 추가 포인터 필드를 포함해야합니다. 반복이 발생하지 않고 큰 인덱스에 사용될 수 있기 때문에 B- 트리의 공간 이점입니다.


1
흥미롭게도, 반복에 대한 생각은 여기의 회신 중에서 독특하며 b + tree의 순서 순회보다 b-tree의 순서 순회보다 더 효율적입니다. 내가 알 수있는 한, b-tree의 순회가 O (n)이고 b + tree에서 가장 작은 노드를 찾는 것이 O (log n) 인 것처럼 전체 이야기가 옳지 않거나 틀린 것입니다. 각 잎을 순회하는 것은 그 외에 O (n)입니다. 그러나 부울 필드와 같이 작은 범위의 값으로 무언가를 인덱싱하는 경우 b + 트리는 중복 처리로 인해 b- 트리보다 훨씬 더 의미가 있습니다.
Eric

1

B + 트리는 나무의 뿌리에서 잎까지의 모든 경로의 길이가 같은 균형 잡힌 나무이며, 나무의 각 비잎 노드는 [n / 2]와 [n]의 자식을 가지며, 여기서 n은 특정 나무에 고정. 색인 페이지와 데이터 페이지가 포함되어 있습니다. 이진 트리에는 부모 노드 당 두 개의 자식 만 있고 B + 트리에는 각 부모 노드에 대해 다양한 수의 자식이있을 수 있습니다.


1
명확성을 위해 B 트리는 이진 트리가 아닙니다. 실제로 B 트리와 B + 트리는 이진 트리보다 구성 및 사용에서 서로 더 가깝습니다. 위키 기사는 정의를 지우는 데 도움이 될 수 있습니다 -B + Tree , B TreeBinary Tree
uutsav

1

B + 트리를 사용할 수있는 한 가지 방법은 트리가 너무 커져 사용 가능한 메모리에 맞지 않는 상황에 적합하다는 것입니다. 따라서 일반적으로 여러 I / O를 수행해야합니다.
B + 트리가 실제로 메모리에 맞는 경우에도 B + 트리가 사용되는 경우가 종종 있으며, 그런 다음 캐시 관리자가이를 영구적으로 유지할 수 있습니다. 그러나 이것은 일반적인 경우가 아닌 특별한 경우이며 캐싱 정책은 B + 트리 유지 관리와 별개입니다.

또한 B + 트리에서 리프 페이지는 연결 목록 (또는 이중 연결 목록)으로 서로 연결되어 순회를 최적화합니다 (범위 검색, 정렬 등). 따라서 포인터 수는 사용되는 특정 알고리즘의 함수입니다.


이것은 왜 우리가 어디서나 B + 트리 대신 B- 트리를 사용해서는 안 되는가에 대한 질문에 대한 답입니다
스택 프로그래머

3
그러나 당신은 우리가 알고있는 한 한쪽 만 설명했습니다. 답변 b-trees는 정확히 같은 방식으로 작동 할 수 있습니다. OP는 차이점을 설명하도록 요청했으며 다른 것에 대해서만 이야기하지 않았습니다. 하나의 원으로 벤 다이어그램을 가질 수 없습니다!
Malfist
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.