Postgresql 9.2.24 문서화 | ||||
---|---|---|---|---|
토토 커뮤니티 : 문서 : 9.2 : 소개 | up | 54 장. SP-Gist 인덱스 | 토토 캔 : 문서 : 9.2 : 구현 |
SP-Gist인터페이스를 제공합니다 높은 수준의 추상화로 액세스 방법이 필요합니다. 주어진 데이터에 특정한 방법 만 구현하는 개발자 유형. 그만큼SP-Gist코어는 효율적인 디스크 매핑 및 트리 검색을 담당합니다 구조. 또한 동시성과 로깅을 처리합니다 고려 사항.
leaf tuples ofSP-Gist트리에는 인덱스 열과 동일한 데이터 유형의 값이 포함되어 있습니다. 루트 레벨의 잎 윈 토토에는 항상 원본이 포함됩니다. 인덱싱 된 데이터 값이지만 낮은 레벨의 잎 윈 토토에는 접미사와 같은 압축 된 표현 만. 이 경우 운영자 클래스 지원 기능은 재구성 할 수 있어야합니다. 내부에서 축적 된 정보를 사용한 원래 값 잎 수준에 도달하기 위해 통과 된 윈 토토.
내부 윈 토토은 분기점이기 때문에 더 복잡합니다. 검색 트리에서. 각각의 내부 윈 토토에는 하나의 세트가 포함되어 있습니다 더노드, 그룹을 대표합니다 비슷한 잎 값. 노드에는 다운 링크가 포함되어 있습니다 다른, 하위 수준 내부 튜플 또는 짧은 잎 목록 모두 같은 색인 페이지에있는 튜플. 각 노드에는에레이블예를 들어, 접미사 트리 노드 레이블이 다음 문자 일 수 있습니다. 문자열 값. 선택적으로, 내부 튜플은 a를 가질 수 있습니다.prefix모든 회원을 설명하는 값. a 접미사 트리 이것은 표현의 일반적인 접두사 일 수 있습니다. 문자열. 접두사 값은 반드시 접두사 일 필요는 없지만 운영자 클래스가 필요한 데이터 일 수 있습니다. 예를 들어, a 쿼드 트리 4 사분면이있는 중심점을 저장할 수 있습니다. 관련하여 측정됩니다. 그런 다음 쿼드 트리 내부 튜플이 될 것입니다 또한 주위의 사분면에 해당하는 4 개의 노드가 포함되어 있습니다 이 중심점.
일부 트리 알고리즘은 레벨 (또는 깊이)에 대한 지식이 필요합니다. 현재 튜플, 그래서SP-Gist코어는 가능성을 제공합니다 내림차순으로 레벨 카운팅을 관리하는 운영자 클래스 나무. 또한 점진적으로 재구성을 지원합니다 필요할 때 대표 값.
참고 :theSP-Gist103PostgreSQL : 문서 : 9.2 : Extensibility99SP-Gist인덱스는 색인 된 열의 널에 대한 저장 항목이 있습니다. 인덱스 연산자 클래스 코드에서 숨겨져 있습니다. 항목 또는 검색 조건은 운영자 클래스 방법. (SP-Gist운영자는 엄격합니다 NULL 값에 대해서는 성공할 수 없습니다.) 따라서 NULL 값이 있습니다 여기서 더 이상 논의되지 않았습니다.
인덱스 운영자가 5 가지 사용자 정의 방법이 있습니다
클래스SP-Gist제공하다. 5 명 모두 2 개를 수락하는 협약을 따릅니다내부인수, 첫 번째는 a
지지를위한 입력 값을 포함하는 C 구조물에 대한 포인터
두 번째 인수는 C 구조물에 대한 포인터입니다.
출력 값을 배치 해야하는 경우. 4 가지 방법은 그냥
반품void, 모든 결과가 나타나기 때문에
출력 구조물에서; 하지만Leaf_consistent
추가로 반환부울결과. 메소드는 수정해서는 안됩니다
입력 구조의 모든 필드. 모든 경우에 출력
사용자 정의를 호출하기 전에 구조물은 0으로 초기화됩니다
방법.
5 가지 사용자 정의 방법은 다음과 같습니다.
config
지수에 대한 정적 정보를 반환합니다 접두사의 데이터 유형 OID를 포함한 구현 및 노드 레이블 데이터 유형.
theSQL선언 함수는 다음과 같아야합니다.
함수 만들기 my_config (내부, 내부) 반환 void ...
첫 번째 인수는 A에 대한 포인터입니다.SPGCONFIGINC 입력을 포함하는 구조 기능에 대한 데이터. 두 번째 논쟁은 포인터입니다 에이SPGCONFIGOUTc 구조 함수는 결과 데이터로 채워야합니다.
typedef struct spgconfigin Oid Atttype; / * 색인화 할 데이터 유형 */ spgconfigin; typedef struct spgconfigout OID PREFIXTYPE; / * 내부 튜플 접두사의 데이터 유형 */ OID LABELTYPE; / * 내부 튜플 노드 레이블의 데이터 유형 */ BOOL CANRETURNDATA; / * opclass는 원본 데이터를 재구성 할 수 있습니다 */ BOOL LONGVALUESOK; / * opclass는 값에 대처할 수 있습니다 1 페이지 */ spgconfigout;
atttype순서대로 전달됩니다 다형성 인덱스 연산자 클래스를 지원하기 위해; 평범한 고정 데이터 유형 운영자 클래스는 항상 있습니다 동일한 값과 무시할 수 있습니다.
접두사를 사용하지 않는 운영자 클래스의 경우PrefixType로 설정할 수 있습니다voidoid. 마찬가지로 운영자를 위해 노드 레이블을 사용하지 않는 클래스,labelType로 설정할 수 있습니다voidoid. CanreturnData운영자 클래스는 재구성 할 수 있습니다 원래 보관 된 인덱스 값.Lo윈 토토Valuesok는 맞아야합니다 때atttype가변 길이와 연산자 클래스가 가능합니다 반복 된 접미사로 긴 값을 분할 ( 참조)섹션 54.3.1).
선택
새 값을 내부에 삽입하는 메소드를 선택합니다. 튜플.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 my_choose (내부, 내부) 반환 void ...
첫 번째 인수는 A에 대한 포인터입니다.SpgchooseinC 구조물, 입력을 포함합니다 기능에 대한 데이터. 두 번째 논쟁은 포인터입니다 에이spgchooseoutc 구조 함수는 결과 데이터로 채워야합니다.
typedef struct spgchoosein 데이텀 데이텀; / * 색인화 될 원본 데이텀 */ 데이텀 리프 듀다; / * 잎에 저장 될 전류 데이텀 */ int 레벨; / * 현재 레벨 (0에서 계산) */ / * 현재 내부 튜플의 데이터 */ BOOL ALLTHESAME; /* 튜플은 모든 것이 표시되어 있습니까? */ BOOL HASPREFIX; /* 튜플에는 접두사가 있습니까? */ Datum Prefixdatum; / * 그렇다면 접두사 값 */ int nnodes; / * 내부 튜플의 노드 수 */ Datum *Nodelabels; / * 노드 레이블 값 (null이 없음) */ spgchoosein; typedef enum spgchooseresulttype spgmatchnode = 1, / * 기존 노드로 내려갑니다 * / spgaddnode, / * 내부 튜플에 노드를 추가하십시오 * / spgsplittuple / * 분할 내부 튜플 (접두사 변경) * / spgchooseresulttype; typedef struct spgchooseout spgchooseresulttype resulttype; / * 액션 코드, 위 참조 */ 노동 조합 spgmatchnode * /struct / * 결과 * / int noden; / *이 노드로 내려갑니다 (0에서 index) */ int levelAdd; / *이 정도의 증분 레벨 */ 데이텀리스트 덤; / * 새로운 잎 기준 */ matchNode; spgaddnode * /struct / * 결과 * / 데이텀 노 델라벨; / * 새 노드 레이블 */ int noden; / * 삽입 할 위치 (0에서 색인) */ addnode; spgsplittuple에 대한 struct / * 결과 * / / * 하나의 노드로 새로운 내부 튜플을 형성하는 정보 */ 부울 접두사 hasprefix; /* 튜플은 접두사가 있어야합니까? */ Datum PrefixprefixDatum; / * 그렇다면 그 가치 */ 데이텀 노 델라벨; / * 노드 레이블 */ / * 모든 오래된 노드와 함께 새로운 하위 수준 내부 튜플을 형성하는 정보 */ bool postfixhasprefix; /* 튜플은 접두사가 있어야합니까? */ Datum postfixprefixdatum; / * 그렇다면 그 가치 */ splittuple; 결과; spgchooseout;
Datum는 원래 데이텀입니다
그것은 색인에 삽입되어야했다.Leafdatum처음에는와 동일합니다.Datum그러나 낮은 곳에서 변경 될 수 있습니다
트리의 레벨 인 경우선택
또는picksplit
메소드를 변경합니다. 언제
삽입 검색은 잎 페이지에 도달합니다.Leafdatum새로 생성 된 잎 윈 토토에 저장됩니다.레벨는 현재 내부 튜플입니다
레벨, 루트 레벨의 경우 0에서 시작합니다.Allthesame현재 내부 인 경우 참입니다
튜플은 여러 동등한 노드를 포함하는 것으로 표시됩니다
(보다섹션
54.3.3).hasprefix사실입니다
전류 내부 튜플에 접두사가 포함 된 경우; 그렇다면,prefixdatum값입니다.nnodes는 자녀의 수입니다
내부 튜플에 포함 된 노드 및Nodelabels는 레이블의 배열입니다
레이블이없는 경우 값 또는 NULL.
the선택
함수는 할 수 있습니다
새로운 값이 하나와 일치하는지 결정하십시오.
기존 자식 노드 또는 새 하위 노드가
추가되었거나 새 값이 튜플과 일치하지 않습니다.
접두사 및 따라서 내부 튜플을 분할하여
덜 제한적인 접두사.
새 가치가 기존 자녀 중 하나와 일치하는 경우 노드, setresulttypetoSPGMATCHNODE. 세트Noden그 인덱스 (제로)로 노드 어레이의 노드. 세트levelAdd증분으로레벨그로 인해 내림차순으로 인한 노동 레벨을 사용합니다. 세트RestdatumTO 동일한Datum운영자 인 경우 클래스 그렇지 않으면로 사용할 수정 된 값으로 설정하십시오.Leafdatum다음 수준.
새 하위 노드를 추가 해야하는 경우resultTypetoSpgaddnode. 세트Nodelabel사용되는 레이블에
새 노드 및 setNodenTO
노드를
노드 어레이. 노드가 추가 된 후선택
함수가 다시 호출됩니다
변형 된 내부 튜플; 그 전화는를 초래해야합니다.SPGMATCHNODE결과.
새 값이 윈 토토 접두사와 일치하지 않는 경우,
세트resulttypetospgsplittuple. 이 행동은 모든 것을 움직입니다
기존 노드는 새로운 하위 수준의 내부 튜플로, 그리고
기존 내부 튜플을 튜플로 대체합니다.
새로운 하위 레벨 내부 튜플에 연결되는 단일 노드.
세트prefixhasprefixTO
새로운 상부 윈 토토에 접두사가 있어야하는지 여부를 나타냅니다.
그리고 그렇게 설정된 경우prefixprefixDatum접두사 값으로.
이 새로운 접두사 값은 충분히 덜 제한적이어야합니다
인덱싱 할 새 값을 수락하려는 원본보다
그리고 그것은 더 이상 원래 접두사보다 더 이상 아니어야합니다. 세트Nodelabel라벨에
새로운 하위 레벨을 가리킬 노드에 사용
내부 튜플. 세트PostFixHaspRefix새로운 하위 수준의 내부 튜플은 접두사가 있어야합니다.
세트PostFixPrefixDatum접두사 값. 이 두 접두사의 조합
추가 레이블은 원본과 동일한 의미를 가져야합니다.
노드를 변경할 기회가 없기 때문에 접두사
새로운 하위 수준 튜플로 이동하거나
자식 색인 항목을 변경하십시오. 노드 후
분할,선택
함수
교체 내부 튜플로 다시 호출됩니다. 저것
통화는 일반적으로를 초래합니다.Spgaddnode아마도 노드이기 때문에 결과
분할 단계에 추가 된 레이블은 새 값과 일치하지 않습니다.
그 후, 마지막으로 세 번째 전화가있을 것입니다.
보고SPGMATCHNODE잎 수준으로 내려 가려는 삽입.
picksplit
세트에 새 윈 토토을 만드는 방법 결정 잎 윈 토토.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 my_picksplit (내부, 내부) 반환 void ...
첫 번째 인수는 a에 대한 포인터입니다.SPGPICKSPLITINc 입력을 포함하는 구조 기능에 대한 데이터. 두 번째 논쟁은 포인터입니다 에이SPGPICKSPLITOUTC 구조, 함수가 결과 데이터로 채워야합니다.
typedef struct spgpicksplitin int ntuples; / * 잎 튜플 수 */ 데이텀 *데이텀; / * 그들의 데이텀 (길이의 배열 ntuples) */ int 레벨; / * 현재 레벨 (0에서 계산) */ spgpicksplitin; typedef struct spgpicksplitout BOOL HASPREFIX; /* 새로운 내부 튜플이 접두사가 있어야합니까? */ Datum Prefixdatum; / * 그렇다면 그 가치 */ int nnodes; / * 새 내부 튜플에 대한 노드 수 */ Datum *Nodelabels; / * 레이블 (또는 레이블 없음) */ int *maptuplestonodes; / * 각 잎에 대한 노드 인덱스 */ 데이텀 *리프트 수스 룸; / * 각각의 새로운 잎 튜플에 보관할 데이 텀 */ spgpicksplitout;
ntuples는 수입니다 제공된 잎 윈 토토.Datums는 데이텀 값의 배열입니다.레벨는 모든 수준입니다 잎 튜플이 공유하며, 새로운 수준이 될 것입니다. 내부 튜플.
SEThasprefix새로운 내부 튜플에 접두사가 있어야하는지 여부, 그렇다면
세트PrefixDatum접두사에
값. 세트nnodes새로운 내부 튜플에 포함 할 노드 수,
그리고 setNodelabels배열로
그들의 레이블 값의. (노드에 레이블이 필요하지 않은 경우
세트Nodelabels보다섹션
54.3.2자세한 내용.) SETMaptuplestonodes제공되는 배열
각 잎이 튜플 인 노드의 인덱스 (0에서)
할당해야합니다. 세트Leaftupledatums의 배열에
새로운 잎 윈 토토에 저장 될 값 (이것들은
입력과 동일Datums운영자 클래스가 한 레벨에서 기준을 수정하지 않는 경우
다음으로).picksplit
함수는
palloc'ing theNodelabels,
MaptuplestonodesandLeaftupledatums배열.
둘 이상의 잎 윈 토토이 제공되면 예상됩니다.
그게picksplit
함수
둘 이상의 노드로 분류합니다. 그렇지 않으면
잎 튜플을 여러 건에 쪼개는 것은 불가능합니다
이 작업의 궁극적 인 목적입니다.
따라서이면picksplit
함수는 모든 잎 튜플을 동일하게 배치하게됩니다.
노드, Core SP-Gist 코드는 해당 결정을 무시하고
잎 튜플이있는 내부 튜플을 생성합니다.
무작위로 여러 동일하게 표지 된 노드에 할당됩니다.
그러한 튜플은 표시되어 있습니다Allthesame이것이 일어났다는 것을 나타냅니다. 그만큼선택
andInner_consistent
함수는 가져와야합니다
그러한 내부 튜플에 적합한 관리. 보다섹션
54.3.3자세한 내용은
picksplit
를 적용 할 수 있습니다
단일 잎 윈 토토에만config
함수 세트Lo윈 토토Valuesoktrue and a
페이지보다 큰 입력 값이 제공되었습니다. 이것에서
사례 작업 지점은 접두사를 벗기는 것입니다.
새롭고 짧은 잎 기준 값을 생성합니다. 전화가 의지합니다
잎 기준이 짧아 질 때까지 반복됩니다.
페이지가 생성되었습니다. 보다섹션
54.3.1자세한 내용은
Inner_consistent
트리 중에 따라야 할 노드 세트 (분기) 세트를 반환합니다 찾다.
theSQL선언 함수는 다음과 같아야합니다.
함수 생성 my_inner_consistent (내부, 내부) 반환 void ...
첫 번째 인수는 A에 대한 포인터입니다.SpginnerConsistentinc 구조물, 포함 함수에 대한 입력 데이터. 두 번째 논쟁은 a A에 대한 포인터SpginnerConsistentOutC 구조 함수는 결과 데이터로 채워야합니다.
typedef struct spginnerconsistentin 스캔 키 스캔 키; / * 운영자 배열 및 비교 값 */ int nkeys; / * 배열 길이 */ Datum ReconstructedValue; / * 부모에게 재구성 된 값 */ int 레벨; / * 현재 레벨 (0에서 계산) */ bool returndata; /* 원본 데이터를 반환해야합니까? */ / * 현재 내부 튜플의 데이터 */ BOOL ALLTHESAME; /* 튜플은 모든 것이 표시되어 있습니까? */ BOOL HASPREFIX; /* 튜플에는 접두사가 있습니까? */ Datum Prefixdatum; / * 그렇다면 접두사 값 */ int nnodes; / * 내부 튜플의 노드 수 */ Datum *Nodelabels; / * 노드 레이블 값 (null이 없음) */ SpginnerConsistentin; typedef struct spginnerconsistentout int nnodes; / * 방문 할 어린이 노드 수 */ int *nodenumbers; / * 노드 어레이의 인덱스 */ int *levelAdds; / * 각 */에 대한 이거 화수율 Datum *재구성 Values; / * 관련 재구성 값 */ spginnerConsistEntOut;
배열Scankeys, OF
길이nkeys,
색인 검색 조건. 이러한 조건이 결합되어 있습니다
그들과 함께 - 그들 모두를 만족시키는 인덱스 항목 만
흥미로운. (nkeys= 0은 모든 인덱스 항목이 쿼리를 만족 함을 의미합니다.)
일반적으로 일관된 함수는에만 관심이 있습니다.sk_strategyandsk_argument각 배열 항목의 필드,
각각 색인 가능한 연산자에게 제공합니다
비교 값. 특히 필요하지 않습니다
확인하다sk_flagsSP-Gist 핵심 코드이기 때문에 비교 값은 null입니다
그러한 조건을 필터링합니다.재구성 value값입니다
부모 윈 토토에 대해 재구성; 그것은(Datum) 0루트 레벨에서 또는Inner_consistent
함수
부모 수준에서 값을 제공하지 않습니다.레벨는 현재 내부 튜플입니다
레벨, 루트 레벨의 경우 0에서 시작합니다.returnDataistrue재구성 된 데이터가 필요한 경우
이 쿼리; 이것은만큼 그렇게 될 것입니다config
기능 주장CanreturnData. Allthesame현재 내부 인 경우 참입니다
튜플이 표시되어"All-the-Same";
이 경우 모든 노드는 동일한 레이블 (있는 경우)을 가지고 있으며
그래서 그들 중 어느 것도 그들 중 전혀 쿼리와 일치합니다 (참조섹션
54.3.3).hasprefix사실입니다
전류 내부 튜플에 접두사가 포함 된 경우; 그렇다면,PrefixDatum값입니다.nnodes는 자녀의 수입니다
내부 튜플에 포함 된 노드 및Nodelabels는 레이블 배열입니다
노드에 레이블이없는 경우 값 또는 NULL.
nnodes방문 해야하는 자식 노드 수
검색 및Nodenumbers필수
인덱스 배열로 설정하십시오. 운영자 클래스 인 경우
레벨을 추적하고 설정levelAdds레벨의 배열로
각 노드로 내림차순이 필요합니다
방문. (종종 이러한 증분은 모두와 동일합니다
노드이지만 반드시 그렇지는 않기 때문에 배열은
중고.) 값 재구성이 필요한 경우재구성의 배열로
방문 할 각 어린이 노드에 대해 재구성 된 값;
그렇지 않으면 떠나재구성null로. 주목하십시오
그만큼Inner_consistent
함수
palloc'ing the에 대한 책임이 있습니다.Nodenumbers, levelAddsand재구성배열.
Leaf_consistent
리프 튜플이 쿼리를 만족시키는 경우 true를 반환합니다.
theSQL선언 함수는 다음과 같아야합니다.
함수 만들기 my_leaf_consistent (내부, 내부) 반환 bool ...
첫 번째 인수는 A에 대한 포인터입니다spleafconsistentinc 구조물, 포함 함수에 대한 입력 데이터. 두 번째 논쟁은 a A에 대한 포인터spleafconsistentoutC 구조 함수는 결과 데이터로 채워야합니다.
typedef struct spleafconsistentin 스캔 키 스캔 키; / * 운영자 배열 및 비교 값 */ int nkeys; / * 배열 길이 */ Datum ReconstructedValue; / * 부모에게 재구성 된 값 */ int 레벨; / * 현재 레벨 (0에서 계산) */ bool returndata; /* 원본 데이터를 반환해야합니까? */ 데이텀 리프 듀다; / * 잎 튜플의 데이텀 */ spgleafconsistentin; typedef struct spgleafconsistentout 데이텀 리프 값; / * 재구성 된 원본 데이터 */ 부울 재건; / * 운영자를 다시 확인 해야하는 경우 true 설정 */ spleafconsistentout;
배열Scankeys, OF
길이nkeys,
색인 검색 조건. 이러한 조건이 결합되어 있습니다
및 - 모든 것을 만족시키는 인덱스 항목 만
쿼리를 만족시킵니다. (nkeys= 0은 모든 인덱스 항목을 의미합니다
쿼리를 만족 시키십시오.) 일반적으로 일관된 기능 만sk_strategy및sk_argument각각의 필드
인덱스 가능한 연산자에게 각각 배열 항목
그리고 비교 값. 특히 필요하지 않습니다
확인하다sk_flagsSP-Gist 핵심 코드이기 때문에 비교 값은 null입니다
그러한 조건을 필터링합니다.재구성 value는 값입니다
부모 윈 토토에 대해 재구성; 그것은(Datum) 0루트 레벨에서 또는Inner_consistent
함수는
부모 수준에서 값을 제공하지 않습니다.레벨현재 잎 튜플 레벨,
루트 레벨의 경우 0에서 시작합니다.returnDataistrue재구성 된 데이터가 필요한 경우
이 쿼리; 이것은만큼 그렇게 될 것입니다config
기능 주장CanreturnData. Leafdatum에 저장된 주요 값입니다
현재 잎 튜플.
함수가 반환해야합니다true리프 윈 토토이 쿼리와 일치하는 경우거짓그렇지 않은 경우. 에서truecase, ifreturnDataistruetheLeafValue값으로 설정해야합니다 이 잎 윈 토토에 대해 원래 색인으로 공급되었습니다. 또한,다시 확인로 설정 될 수 있습니다true경기가 불확실한 경우 따라서 연산자는 실제 힙에 다시 적용되어야합니다. 경기를 확인하려면 윈 토토.
모든 SP-Gist 지원 방법은 일반적으로
단기간 메모리 컨텍스트; 즉,CurrentMemoryContext이후에 재설정됩니다
각 튜플의 처리. 따라서 그다지 중요하지 않습니다
당신이 palloc 모든 것을 pfree'i윈 토토에 대해 걱정하십시오. (그만큼config
메소드는 예외입니다
메모리가 새는 것을 피하십시오. 그러나 보통config
메소드는 할당하는 것 외에는 아무것도하지 않아야합니다
전달 된 매개 변수 구조물로의 상수.)
인덱스 된 열이 Collatable Data Type 인 경우 인덱스
Collation은 다음을 사용하여 모든 지원 방법으로 전달됩니다.
기준pg_get_collation ()
메커니즘.