이 문서는 지원되지 않는 PostgreSQL 버전에 대한 것입니다.
다음에 대한 동일한 페이지를 보고 싶을 수도 있습니다.PostgreSQL : 문서 : 17 : 36.16. 와이즈 토토에 대한 확장 인터페이스버전 또는 위에 나열된 다른 지원 버전 중 하나를 사용하세요.

32.14. 인터페이스 토토 캔 확장

지금까지 설명한 절차를 통해 새로운 유형을 정의할 수 있습니다. 새로운 함수와 새로운 연산자. 그러나 아직은 정의할 수 없습니다. 새로운 데이터 유형의 열에 대한 인덱스입니다. 이를 위해 우리는 다음과 같이 해야 합니다. 정의하다연산자 클래스새로운 것을 위해 데이터 유형. 이 섹션의 뒷부분에서 이 개념을 설명하겠습니다. 예: B-트리 인덱스 메소드에 대한 새로운 연산자 클래스 복소수를 절대값 오름차순으로 저장하고 정렬하는 방법 주문하다.

참고:이전포스트그레SQL릴리스 7.3, 필요했습니다 시스템 카탈로그에 수동으로 추가하기 위해pg_amop, pg_amprocpg_opclass을 만들기 위해 사용자 정의 연산자 클래스. 해당 접근 방식은 이제 더 이상 사용되지 않습니다. 사용에 찬성연산자 클래스 생성입니다. 훨씬 간단하고 오류가 덜 발생하는 방법입니다. 필요한 카탈로그 항목입니다.

32.14.1. 인덱스 메소드 및 연산자 클래스

pg_am테이블에는 하나가 포함되어 있습니다. 모든 인덱스 방법(내부적으로는 액세스 방법이라고 함)에 대한 행입니다. 테이블에 대한 정기적인 액세스 지원이 내장되어 있습니다.PostgreSQL, 그러나 모든 색인 방법은 설명됨pg_am. 그것은 필요한 항목을 정의하여 새로운 색인 방법을 추가할 수 있습니다. 인터페이스 루틴을 생성한 다음 행을 생성합니다.pg_am— 하지만 그건 이 범위를 벗어납니다. 장(참조PostgreSQL : 문서 : 8.1 : 색인 토토 베이 방법 인터페이스 정의).

토토 캔 메소드에 대한 루틴은 직접적으로 알지 못합니다. index 메소드가 사용할 데이터 유형에 관한 모든 것 작동합니다. 대신에,연산자 수업식별합니다 인덱스 메서드가 작동하는 데 사용해야 하는 작업 집합 특정 데이터 유형을 사용합니다. 연산자 클래스는 소위 왜냐하면 그들이 지정하는 한 가지는어디에서-와 함께 사용할 수 있는 절 연산자 인덱스(즉, 인덱스 스캔으로 변환될 수 있음) 자격). 연산자 클래스는 일부를 지정할 수도 있습니다.지원 절차다음에 의해 필요합니다. 인덱스 메서드의 내부 작업은 수행하지 않지만 임의의 것에 직접 대응함어디-와 함께 사용할 수 있는 절 연산자 색인.

여러 연산자 클래스를 정의할 수 있습니다. 동일한 데이터 유형 및 인덱스 방법. 이렇게 하면 여러 세트가 단일 데이터 유형에 대해 인덱싱 의미론을 정의할 수 있습니다. 예를 들어, B-트리 인덱스에는 정렬 순서가 필요합니다. 작동하는 각 데이터 유형에 대해 정의됩니다. 다음 용도로 유용할 수 있습니다. 하나의 B-트리 연산자 클래스를 갖는 복소수 데이터 유형 복소 절대값을 기준으로 데이터를 정렬하는 방법과 실수 부분별로 정렬합니다. 일반적으로 운영자 중 한 명이 클래스는 가장 일반적으로 유용한 것으로 간주되어 표시됩니다. 해당 데이터 유형 및 인덱스에 대한 기본 연산자 클래스로 방법.

동일한 연산자 클래스 이름을 여러 항목에 사용할 수 있습니다. 다양한 인덱스 방법(예: B-트리와 해시 모두) 인덱스 메소드에는 이름이 지정된 연산자 클래스가 있습니다.int4_ops), 그러나 그러한 각 클래스는 독립적입니다. 엔터티이며 별도로 정의해야 합니다.

32.14.2. 색인 방법 전략

연산자 클래스와 연관된 연산자는 다음과 같습니다. 다음으로 식별됨"전략 수치", 이는 각 연산자의 의미를 식별하는 데 사용됩니다. 연산자 클래스의 컨텍스트. 예를 들어, B-트리는 키에 대한 엄격한 순서, 작은 것부터 큰 것까지, 그래서 연산자 좋다"미만"그리고"크거나 같음"흥미롭네요 B-트리를 존중합니다. 왜냐하면PostgreSQL사용자가 정의할 수 있습니다. 연산자,포스트그레SQL할 수 없습니다 연산자 이름을 확인하세요(예:<또는=) 그리고 말해 그게 무슨 비교인지. 대신에 인덱스 방식은 의 집합을 정의합니다."전략", 일반화된 연산자로 생각할 수 있습니다. 각 연산자 클래스 각 전략에 해당하는 실제 연산자를 지정합니다. 특정 데이터 유형 및 인덱스 해석에 대한 의미론.

B-트리 인덱스 방법은 다음과 같이 5가지 전략을 정의합니다.테이블 32-2.

표 32-2. B-트리 전략

작동 전략 번호
미만 1
작거나 같음 2
같음 3
크거나 같음 4
보다 큼 5

해시 색인은 비트별 동일성만 표현하므로 다음을 사용합니다. 단 하나의 전략, 다음에 표시됨표 32-3.

표 32-3. 해시 전략

작동 전략 번호
같음 1

R-트리 토토 캔는 관계를 2차원으로 표현합니다. 공간. 그들은 12가지 전략을 사용합니다.표 32-4. 4개 이는 진정한 2차원 테스트입니다(겹침, 동일, 포함, 포함); 그 중 4개는 X 방향만 고려합니다. 그리고 나머지 4개는 Y 방향으로 동일한 테스트를 제공합니다.

표 32-4. R-트리 전략

작동 전략 번호
완전히 왼쪽 1
오른쪽으로 확장되지 않음 2
겹침 3
왼쪽으로 확장되지 않음 4
완전히 오른쪽 5
동일 6
포함 7
다음에 의해 포함됨 8
위로 확장되지 않음 9
엄격히 아래 10
엄격히 위 11
아래로 확장되지 않음 12

GiST 토토 캔는 훨씬 더 유연합니다. 전혀 고정된 전략 세트. 대신에"일관성"각 특정의 지원 루틴 GiST 연산자 클래스는 전략 번호를 해석하지만 좋아요.

모든 전략 연산자는 부울 값을 반환합니다. ~ 안에 실제로 인덱스 방법 전략으로 정의된 모든 연산자는 다음을 수행해야 합니다. 반환 유형부울, 그래야 하기 때문에 a의 최상위 수준에 나타납니다.어디색인과 함께 사용되는 절입니다.

그런데, 그amorderstrategy열 inpg_am여부를 알려줍니다. 인덱스 방법은 순서가 지정된 스캔을 지원합니다. 0은 그렇지 않음을 의미합니다. 그렇다면,amorderstrategy이것은 순서 연산자에 해당하는 전략 번호입니다. 을 위한 예를 들어, B-트리에는amorderstrategy= 1, 이는 그"미만"전략 번호.

32.14.3. 인덱스 방법 지원 루틴

전략은 일반적으로 시스템에 대한 정보가 충분하지 않습니다. 인덱스를 어떻게 사용하는지 알아보세요. 실제로는 인덱스 방법이 작동하려면 추가 지원 루틴이 필요합니다. 예를 들어, B-트리 인덱스 방법은 다음을 비교할 수 있어야 합니다. 두 개의 키를 사용하여 하나가 더 큰지, 같은지 확인합니다. 또는 다른 것보다 적습니다. 마찬가지로 R-트리 인덱스 방법은 다음과 같아야 합니다. 교집합, 합집합, 크기를 계산할 수 있습니다. 직사각형. 이 작업은 연산자에 해당하지 않습니다. SQL 명령의 자격에 사용됩니다. 그들은 행정적이다 내부적으로 인덱스 메서드에서 사용되는 루틴입니다.

전략과 마찬가지로 연산자 클래스는 특정 기능은 주어진 상황에 대해 이러한 각 역할을 수행해야 합니다. 데이터 유형 및 의미 해석. 인덱스 메소드는 다음을 정의합니다. 필요한 함수 세트와 연산자 클래스 에 할당하여 사용할 올바른 기능을 식별합니다. 그만큼"지원 기능 번호".

B-트리에는 다음과 같은 단일 지원 기능이 필요합니다.표 32-5.

표 32-5. B-트리 지원 함수

기능 지원 번호
두 개의 키를 비교하여 다음보다 작은 정수를 반환합니다. 0, 0 또는 0보다 큼(다음 여부를 나타냄) 첫 번째 키가 보다 작거나, 같거나, 큽니다. 두 번째. 1

해시 인덱스에도 마찬가지로 하나의 지원 기능이 필요합니다.테이블 32-6.

표 32-6. 해시 지원 함수

기능 지원 번호
키의 해시 값 계산 1

R-트리 인덱스에는 다음과 같은 세 가지 지원 기능이 필요합니다.테이블 32-7.

표 32-7. R-트리 지원 함수

기능 지원 번호
연합 1
교차로 2
크기 3

GiST 인덱스에는 7가지 지원 기능이 필요합니다.테이블 32-8.

표 32-8. GiST 지원 기능

기능 지원 번호
일관적인 1
연합 2
압축 3
압축해제 4
페널티 5
picksplit 6
같음 7

전략 연산자와 달리 지원 함수 반환 특정 인덱스 메소드가 예상하는 데이터 유형이 무엇이든; ~을 위한 B-트리에 대한 비교 함수의 예 부호 있는 정수.

32.14.4. 예

이제 우리는 아이디어를 보았고 여기에 약속된 것이 있습니다 새로운 연산자 클래스를 생성하는 예입니다. (당신은 찾을 수 있습니다 이 예제의 작업 복사본은src/tutorial/complex.c그리고src/tutorial/complex.sql소스에서 분포.) 연산자 클래스는 다음과 같은 연산자를 캡슐화합니다. 복소수를 절대값 순서로 정렬하므로 다음을 선택합니다. 이름complex_abs_ops. 먼저, 우리는 연산자 집합입니다. 연산자를 정의하는 절차는 다음과 같습니다. 에서 논의됨와이즈 토토 : 문서 : 8.1 : 사용자 정의 연산자. 대한 B-트리의 연산자 클래스에서 필요한 연산자는 다음과 같습니다.

  • 절대값보다 작음(전략 1)
  • 절대값이 작거나 같음(전략 2)
  • 절대값 동일(전략 3)
  • 절대값 크거나 같음(전략 4)
  • 절대값보다 큼(전략 5)

관련 세트를 정의하는 오류가 최소화되는 방법 비교 연산자는 B-트리 비교 지원을 작성하는 것입니다. 함수를 먼저 작성한 다음 다른 함수를 한 줄로 작성합니다. 지원 기능을 둘러싼 래퍼. 이렇게 하면 확률이 줄어듭니다. 코너 케이스에 대해 일관되지 않은 결과를 얻습니다. 이에 따라 접근 방식, 먼저 작성합니다

#define Mag(c) ((c)-x*(c)-x + (c)-y*(c)-y)

정적 정수
complex_abs_cmp_internal(복소수 *a, 복소수 *b)

    이중 amag = Mag(a),
                bmag = Mag(b);

    if (amag < bmag)
        -1을 반환합니다.
    if (amag  bmag)
        1을 반환합니다.
    0을 반환합니다.

이제 미만 함수는 다음과 같습니다.

PG_FUNCTION_INFO_V1(complex_abs_lt);

자료
complex_abs_lt(PG_FUNCTION_ARGS)

    복소수 *a = (복소수 *) PG_GETARG_POINTER(0);
    복소수 *b = (복소수 *) PG_GETARG_POINTER(1);

    PG_RETURN_BOOL(complex_abs_cmp_internal(a, b) < 0);

다른 네 가지 기능은 비교 방법만 다릅니다. 내부 함수의 결과는 0입니다.

다음으로 우리는 다음을 기반으로 함수와 연산자를 선언합니다. SQL에 대한 함수:

CREATE FUNCTION complex_abs_lt(complex, complex) RETURNS bool
    처럼 '파일 이름', 'complex_abs_lt'
    언어 C 불변 STRICT;

연산자 만들기 < (
   leftarg = 복잡함, rightarg = 복잡함, 프로시저 = complex_abs_lt,
   정류자 =  , 부정자 = = ,
   제한 = scalarltsel, 조인 = scalarltjoinsel
);

올바른 정류자를 지정하는 것이 중요하며 부정 연산자, 적절한 제한 및 조인 선택성 기능, 그렇지 않으면 최적화 프로그램이 작동하지 않습니다. 인덱스를 효과적으로 활용하려면 보다 작음에 유의하세요. 같음과 큼의 경우에는 서로 다른 선택성을 사용해야 합니다. 기능.

여기서 주목할만한 다른 일들이 일어나고 있습니다:

  • 예를 들어, 이름이 지정된 연산자는 하나만 있을 수 있습니다.=그리고 유형을 취하고복잡한두 피연산자 모두에 대해. 이 경우 우리는 다른 연산자가 없습니다=for복잡한, 하지만 우리가 건물을 짓고 있다면 우리가 원하는 실용적인 데이터 유형=다음에 대한 일반적인 동등 연산이 됩니다. 복소수(절대값의 동일성은 아님) 값). 이 경우 다른 연산자를 사용해야 합니다. 이름complex_abs_eq.

  • 하지만PostgreSQL할 수 있다 동일한 SQL 이름을 갖는 함수에 대처합니다. 그들은 서로 다른 인수 데이터 유형을 가지고 있으며 C는 단지 대처할 수 있습니다 주어진 이름을 가진 하나의 전역 함수를 사용합니다. 그래서 우리는 C 함수 이름을 다음과 같이 간단하게 지정하면 안 됩니다.abs_eq. 보통은 좋은데 C 함수에 데이터 유형 이름을 포함하는 연습 다른 데이터에 대한 기능과 충돌하지 않도록 이름 유형.

  • 우리는 함수의 SQL 이름을 만들 수 있었습니다abs_eq, 의지함PostgreSQL그것을 구별하기 위해 동일한 다른 SQL 함수의 인수 데이터 유형 이름. 예제를 단순하게 유지하기 위해 함수를 다음과 같이 만듭니다. C 레벨과 SQL 레벨에서 동일한 이름입니다.

다음 단계는 지원 루틴을 등록하는 것입니다 B-트리에 필요합니다. 이를 구현하는 예제 C 코드는 다음과 같습니다. 연산자 함수가 포함된 동일한 파일에 있습니다. 이것은 함수를 선언하는 방법:

CREATE FUNCTION complex_abs_cmp(복합,복잡)
    정수를 반환합니다.
    처럼 '파일 이름'
    언어 C 불변 STRICT;

이제 필요한 연산자와 지원 루틴이 있으므로, 마침내 연산자 클래스를 만들 수 있습니다.

연산자 클래스 생성 complex_abs_ops
    btree AS를 사용하는 유형 콤플렉스의 기본값
        연산자 1 < ,
        연산자 2 <= ,
        연산자 3 = ,
        연산자 4 = ,
        연산자 5  ,
        기능 1 complex_abs_cmp(복잡함,복잡함);

그리고 우리는 끝났습니다! 이제 생성 및 사용이 가능해졌습니다. B-트리 인덱스:복잡한열.

우리는 연산자 항목을 더 장황하게 작성할 수도 있었습니다. 에서와 같이

연산자 1 < (복잡함, 복잡함) ,

그러나 운영자가 연산자 클래스를 정의하는 것과 동일한 데이터 유형입니다.

위의 예는 귀하가 이것을 새로 만들고 싶다고 가정합니다 연산자 클래스는 에 대한 기본 B-트리 연산자 클래스입니다.복잡한데이터 유형. 그렇지 않다면 그냥 단어를 생략하세요기본값.

32.14.5. 교차 데이터 유형 연산자 수업

지금까지 우리는 연산자 클래스가 하나의 데이터 유형만 다룹니다. 확실히 있을 수 있지만 특정 인덱스 열에는 하나의 데이터 유형만 있는 경우가 많습니다. 인덱싱된 열을 비교하는 인덱스 작업에 유용합니다. 다른 데이터 유형의 값. 이는 현재 다음에서 지원됩니다. B-트리 및 GiST 인덱스 방법.

B-트리에서는 각 연산자의 왼쪽 피연산자가 다음과 같아야 합니다. 인덱스된 데이터 유형이지만 오른쪽 피연산자는 다음과 같을 수 있습니다. 다른 유형. 지원 기능이 있어야 합니다. 일치하는 서명. 예를 들어, 내장 연산자 클래스 유형에 대해bigint (int8)은 유형 간 비교를 허용합니다.int4그리고int2. 그럴 수도 있지 이 정의에 의해 중복됨:

연산자 클래스 int8_ops 생성
btree AS를 사용하는 int8 유형의 기본값
  -- 표준 int8 비교
  연산자 1 < ,
  연산자 2 <= ,
  연산자 3 = ,
  연산자 4 = ,
  연산자 5  ,
  기능 1 btint8cmp(int8, int8) ,

  -- int2(smallint)와의 유형 간 비교
  연산자 1 < (int8, int2) ,
  연산자 2 <= (int8, int2) ,
  연산자 3 = (int8, int2) ,
  연산자 4 = (int8, int2) ,
  연산자 5  (int8, int2) ,
  기능 1 btint82cmp(int8, int2) ,

  -- int4(정수)와의 유형 간 비교
  연산자 1 < (int8, int4) ,
  연산자 2 <= (int8, int4) ,
  연산자 3 = (int8, int4) ,
  연산자 4 = (int8, int4) ,
  연산자 5  (int8, int4) ,
  함수 1 btint84cmp(int8, int4) ;

이 정의에 주목하세요"과부하"운영자 전략 및 지원 기능 번호. 이는 허용됩니다(B-트리 연산자 클래스의 경우). 만) 특정 숫자의 각 인스턴스에 다른 오른쪽 데이터 유형. 그렇지 않은 사례는 교차 유형은 연산자의 기본 또는 기본 연산자입니다. 수업.

GiST 인덱스는 전략이나 지원의 과부하를 허용하지 않습니다. 함수 번호를 사용하지만 여전히 다음과 같은 효과를 얻을 수 있습니다. 여러 오른쪽 데이터 유형을 지원합니다. 각 운영자에게 고유한 전략 번호가 필요합니다. 지원됩니다. 그만큼일관적인지원 함수는 다음을 기반으로 수행해야 할 작업을 결정해야 합니다. 전략 번호이며 비교를 수용할 준비가 되어 있어야 합니다. 적절한 데이터 유형의 값.

32.14.6. 시스템 종속성 연산자 클래스

PostgreSQL연산자를 사용합니다 다양한 방법으로 연산자의 속성을 추론하는 클래스 단지 인덱스와 함께 사용할 수 있는지 여부입니다. 그러므로 당신은 연산자 클래스가 없더라도 연산자 클래스를 만들고 싶을 수도 있습니다. 데이터 유형의 모든 열을 색인화하려는 의도입니다.

특히 다음과 같은 SQL 기능이 있습니다.주문 기준그리고독특값 비교 및 ​​정렬이 필요합니다. 구현하려면 사용자 정의 데이터 유형에 대한 이러한 기능PostgreSQL기본 B-트리를 찾습니다 데이터 유형에 대한 연산자 클래스입니다. 그만큼"같음"이 연산자 클래스의 구성원은 다음을 정의합니다. 가치의 평등에 대한 시스템의 개념그룹별그리고특수, 연산자 클래스에 의해 부과된 정렬 순서는 기본주문 기준주문합니다.

사용자 정의 유형의 배열 비교는 또한 다음 사항에 의존합니다. 기본 B-트리 연산자 클래스에 의해 정의된 의미.

데이터에 대한 기본 B-트리 연산자 클래스가 없는 경우 유형을 입력하면 시스템은 기본 해시 연산자 클래스를 찾습니다. 하지만 그런 종류의 연산자 클래스는 동등성만을 제공하기 때문에 실제로는 배열 동등성을 지원하는 데만 충분합니다.

데이터 유형에 대한 기본 연산자 클래스가 없는 경우, 다음과 같은 오류가 발생합니다."식별할 수 없습니다 주문 연산자"이 SQL 기능을 사용하려고 하면 데이터 유형으로.

참고:PostgreSQL7.4 이전 버전, 정렬 및 그룹화 작업은 암시적으로 이름이 지정된 연산자=, <. 그만큼 기본 연산자 클래스에 의존하는 새로운 동작으로 의 행동에 대해 어떠한 가정도 해야 함 특정 이름을 가진 연산자.

32.14.7. 오퍼레이터의 특징 수업

연산자 클래스에는 두 가지 특별한 기능이 있습니다. 아직 논의하지 않았습니다. 주로 유용하지 않기 때문입니다. 가장 일반적으로 사용되는 색인 방법입니다.

일반적으로 연산자를 연산자의 구성원으로 선언합니다. 클래스는 토토 캔 메소드가 세트를 정확하게 검색할 수 있음을 의미합니다. a를 만족하는 행의 수어디에서조건 연산자를 사용합니다. 예를 들어,

SELECT * FROM table WHERE 정수_열 < 4;

정수에 대한 B-트리 인덱스로 정확히 충족될 수 있습니다. 열. 하지만 인덱스가 유용한 경우도 있습니다. 일치하는 행에 대한 부정확한 가이드입니다. 예를 들어, R-트리인 경우 인덱스는 객체에 대한 경계 상자만 저장하므로 정확히 a를 만족시키다어디에서조건은 다음과 같습니다 다각형과 같은 직사각형이 아닌 객체 사이의 겹침을 테스트합니다. 그러나 경계 상자가 있는 객체를 찾기 위해 인덱스를 사용할 수 있습니다. 대상 객체의 경계 상자와 겹치고 다음을 수행합니다. 인덱스에서 찾은 객체에 대해서만 정확한 중첩 테스트를 수행합니다. 만약에 이 시나리오가 적용되며 인덱스는 다음과 같습니다."손실"연산자에 대해 추가합니다다시 확인운영자오퍼레이터 클래스 생성명령.다시 확인색인이 다음과 같은 경우 유효합니다. 필요한 모든 행을 반환하는 것이 보장됩니다. 일부 추가 행은 다음을 수행하여 제거할 수 있습니다. 원래 연산자 호출.

우리가 다음과 같은 복잡한 객체의 경계 상자만 색인화합니다. 다각형. 이 경우에는 저장하는 데 큰 가치가 없습니다. 인덱스 항목에 전체 폴리곤을 저장합니다. 더 간단한 유형의 객체상자. 이것 상황은 다음과 같이 표현됩니다.저장옵션 포함연산자 클래스 생성: 우리는 다음과 같이 작성하세요

연산자 클래스 생성polygon_ops
    gist AS를 사용하는 유형 다각형의 기본값
        ...
        저장 상자;

현재 GiST 인덱스 방법만 다음을 지원합니다.저장열과 다른 유형 데이터 유형. GiST압축그리고압축해제지원 루틴이 처리해야 함 다음과 같은 경우 데이터 유형 변환을 사용합니다.저장사용됩니다.