지금까지 설명한 절차를 통해 새로운 유형, new 함수와 새로운 연산자. 그러나 아직은 정의할 수 없습니다. 보조 인덱스(예:B-트리, R-트리또는 해시 액세스 방법)을 통해 새로운 유형 또는 해당 연산자.
뒤를 돌아보세요주요 Postgres 시스템 카탈로그. 오른쪽 절반에는 수정해야 하는 카탈로그가 표시됩니다. 말해주기 위해포스트그레스방법 사용자 정의 유형 및/또는 사용자 정의 연산자를 인덱스와 함께 사용 (즉,pg_am, pg_amop, pg_amproc, pg_operator그리고pg_opclass). 불행히도 이를 수행하는 간단한 명령은 없습니다. 우리는 실행 예제를 통해 이러한 카탈로그를 수정하는 방법을 보여줍니다. 에 대한 새로운 연산자 클래스B-트리복소수를 오름차순으로 저장하고 정렬하는 액세스 방법 절대값 순서메이저 토토 사이트.
그pg_am클래스에는 하나의 인스턴스가 포함되어 있습니다. 모든 사용자 정의 액세스 방법에 대해. 힙 액세스 지원 메소드가 내장되어 있습니다.포스트그레스하지만 다른 모든 액세스 방법은 여기에 설명되어 있습니다. 스키마는
표 43-1. 인덱스 스키마
| 속성 | 설명 |
|---|---|
| amname | 액세스 방법 이름 |
| 아소유자 | 소유자의 개체 ID pg_user의 인스턴스 |
| 좋은 전략 | 이를 위한 전략 수 액세스 방법(아래 참조) |
| 암지원 | 다음에 대한 지원 루틴 수 이 액세스 방법(아래 참조) |
| amorderstrategy | 인덱스가 no를 제공하는 경우 0입니다. 정렬 순서, 그렇지 않으면 전략의 전략 번호 정렬 순서를 설명하는 연산자 |
| amgettuple | |
| 아민서트 | |
| ... | 프로시저 식별자 액세스 방법에 대한 인터페이스 루틴메이저 토토 사이트. 예를 들어, regproc 인스턴스를 열고 닫고 가져오기 위한 ID 액세스 방법이 여기에 표시됩니다. |
그객체 ID인스턴스의pg_am은 많은 경우 외래 키로 사용됩니다. 다른 수업. 이 클래스에 새 인스턴스를 추가할 필요는 없습니다. 당신이 관심을 갖고 있는 것은 바로 그 것메이저 토토 사이트.객체 아이디확장하려는 액세스 방법 인스턴스의:
pg_am에서 oid 선택 amname = 'btree'; 이드 ----- 403 (1행)우리는 그것을 사용하겠습니다선택에어디에서다음 절.
그좋은 전략속성이 다음에 존재합니다. 데이터 유형 전반에 걸쳐 비교를 표준화합니다. 예를 들어,B-트리s는 엄격한 명령을 내립니다. 키가 작을수록 커집니다. 이후포스트그레스사용자가 연산자를 정의할 수 있습니다.포스트그레이름을 볼 수 없습니다 연산자(예: "" 또는 "<")를 선택하고 어떤 종류인지 알려주세요. 비교는 그렇죠. 실제로 일부 액세스 방법은 어떠한 요구사항도 부과하지 않습니다. 전혀 주문합니다. 예를 들어,R-트리s 직사각형-포함 관계를 표현하는 반면, 해시된 데이터는 구조는 a의 값을 기반으로 비트별 유사성만 표현합니다. 해시 함수.포스트그레스좀 필요해요 귀하의 쿼리에서 자격을 취득하는 일관된 방법을 살펴보고 연산자를 사용하고 사용 가능한 인덱스가 있는지 결정합니다. 이 다음을 의미합니다.포스트그레필요 예를 들어, "<=" 및 "" 연산자가 분할된다는 것을 알고 있습니다. 에B-트리. 포스트그레전략을 사용하여 이를 표현합니다. 연산자 간의 관계와 연산자를 사용하는 방법 인덱스를 스캔합니다.
새로운 전략 세트를 정의하는 것은 이 범위를 벗어납니다. 논의하고 있지만 방법을 설명하겠습니다.B-트리전략은 효과가 있습니다. 왜냐하면 당신이 알아야 하기 때문메이저 토토 사이트 새로운 연산자 클래스를 추가하는 것메이저 토토 사이트. 에서pg_am클래스, amstrategies 속성은 이 액세스 방법에 대해 정의된 전략 수입니다. 에 대한B-트리s, 이 숫자는 5입니다. 전략은 다음과 같습니다
표 43-2. B-트리 전략
| 작동 | 색인 |
|---|---|
| 미만 | 1 |
| 작거나 같음 | 2 |
| 같음 | 3 |
| 크거나 같음 | 4 |
| 보다 큼 | 5 |
아이디어는 다음과 같은 절차를 추가해야 한다는 것입니다. 위의 비교는pg_amop관계(아래 참조). 액세스 방법 코드는 이러한 전략을 사용할 수 있습니다 데이터 유형에 관계없이 숫자를 사용하여 분할 방법을 알아보세요.B-트리, 선택성 계산 및 등등. 프로시저 추가에 대한 세부 사항은 아직 걱정하지 마세요. 그냥 다음과 같은 일련의 절차가 있어야 함을 이해합니다.int2, int4, oid,및 기타 모든 데이터 어떤 것을 입력하세요.B-트리할 수 있다 작동합니다.
때때로 전략은 시스템에 대한 정보가 충분하지 않습니다. 인덱스를 어떻게 사용하는지 알아보세요. 일부 액세스 방법에는 다음이 필요합니다. 작동하기 위한 다른 지원 루틴. 예를 들어,B-트리액세스 방법은 다음을 수행할 수 있어야 합니다. 두 개의 키를 비교하고 하나가 더 큰지, 같은지 확인합니다. 다른 것보다 적거나 적습니다. 마찬가지로,R-트리액세스 방법은 다음을 계산할 수 있어야 합니다. 교차점, 합집합 및 직사각형의 크기. 이러한 작업은 SQL 쿼리의 사용자 자격과 일치하지 않습니다. 그들은 내부적으로 액세스 방법에 사용되는 관리 루틴입니다.
다양한 지원 루틴을 일관되게 관리하기 위해 모두포스트그레액세스 방법,pg_am라는 속성을 포함합니다암지원. 이 속성은 다음을 기록합니다. 액세스 방법에서 사용되는 지원 루틴의 수입니다. 에 대한B-트리s, 이 숫자는 1입니다 -- 두 개의 키를 가져와서 다음에 따라 -1, 0 또는 +1을 반환하는 루틴입니다. 첫 번째 키가 키보다 작거나 같거나 큰지 여부 두 번째.
참고:엄밀히 말하면 이 루틴은 다음을 반환할 수 있습니다. 음수(< 0), 0 또는 0이 아닌 양수( 0).
그전략입력pg_am은 단지 다음에 대해 정의된 전략의 수입니다. 문제의 액세스 방법. 미만, 미만에 대한 절차 같음 등은 표시되지 않습니다.pg_am. 마찬가지로,암지원그냥 숫자일 뿐이야 액세스 방법에 필요한 지원 루틴의 수입니다. 실제 루틴은 다른 곳에 나열되어 있습니다.
그런데, 그amorderstrategy항목 액세스 방법이 순차적 스캔을 지원하는지 여부를 알려줍니다. 0은 다음을 의미합니다. 그렇지 않습니다. 그렇다면,amorderstrategy는 다음에 해당하는 전략 루틴의 번호입니다. 주문 연산자. 예를 들어, btree에는amorderstrategy= 1은 "보다 작음"입니다. 전략 번호.
다음 관심 클래스는pg_opclass. 이 클래스는 연결을 위해서만 존재합니다. 연산자 클래스 이름 및 연산자가 포함된 기본 유형 클래스 oid. 일부 기존 opclass는 다음과 같습니다.int2_ops, int4_ops,그리고oid_ops. 다음을 사용하여 인스턴스를 추가해야 합니다. opclass 이름(예:complex_abs_ops) ~pg_opclass.oid의 이 인스턴스는 특히 다른 클래스의 외래 키가 됩니다.pg_amop.
pg_opclass에 삽입(opcname, opcdeftype)
SELECT 'complex_abs_ops', oid FROM pg_type WHERE typname = 'complex';
SELECT oid, opcname, opcdeftype
pg_opclass에서
opcname = 'complex_abs_ops';
이드 | opc이름 | opcdeftype
------+------+------------
277975 | complex_abs_ops | 277946
(1행)귀하의 oid에 유의하십시오.pg_opclass인스턴스는 다를 것입니다! 걱정하지 마세요
그래도 이것에 대해서는. 나중에 시스템에서 이 번호를 받게 됩니다.
여기서 유형의 oid를 얻은 것처럼요.위의 예는 귀하가 이 새로운 opclass를 만들고 싶다고 가정합니다 에 대한 기본 인덱스 opclass복잡한데이터 유형. 그렇지 않은 경우에는 0을 삽입하세요.opcdeftype, 데이터 유형을 삽입하는 대신 oid:
pg_opclass에 삽입(opcname, opcdeftype) VALUES('complex_abs_ops', 0);
이제 접근 방법과 연산자 클래스가 생겼습니다. 우리는 아직도 일련의 연산자가 필요합니다. 연산자를 정의하는 절차는 다음과 같습니다. 이 설명서의 앞부분에서 논의했습니다. 에 대한complex_abs_opsBtrees의 연산자 클래스, 우리에게 필요한 연산자는 다음과 같습니다:
절대값보다 작음
절대값이 작거나 같음
절대값이 같음
절대값 크거나 같음
절대값보다 큼
정의된 함수를 구현하는 코드가 저장되어 있다고 가정합니다. 파일에서PGROOT/src/tutorial/complex.c
C 코드의 일부는 다음과 같습니다: (우리는 단지 나머지 예제에서는 항등 연산자입니다. 나머지 4개 연산자는 매우 유사합니다. 참조복잡한.c또는복합체.소스자세한 내용은.)
#define Mag(c) ((c)-x*(c)-x + (c)-y*(c)-y)
부울
complex_abs_eq(복소수 *a, 복소수 *b)
이중 amag = Mag(a), bmag = Mag(b);
return (amag==bmag);
우리는 다음과 같이 Postgres에 함수를 알려줍니다.
CREATE FUNCTION complex_abs_eq(복합,복잡)
반환 부울
AS 'PGROOT/tutorial/obj/complex.so'
언어 'c';
여기서 몇 가지 중요한 일이 일어나고 있습니다.
먼저, 작음, 작거나 같음, 같음, 크거나 같음 및 보다 큼복잡한정의 중메이저 토토 사이트. 우리는 하나만 가질 수 있어요 연산자 이름은 =이고 유형을 취함복잡한두 피연산자 모두에 대해. 이 경우에는 그렇지 않습니다. 다른 연산자가 있음 = for복잡한, 하지만 실용적인 데이터 유형을 구축한다면 아마도 다음을 원할 것입니다. 복소수에 대한 일반적인 동등 연산이 됩니다. 그 안에 이 경우에는 다른 연산자 이름을 사용해야 합니다. complex_abs_eq.
둘째, Postgres는 다음과 같은 연산자를 사용할 수 있지만 입력 데이터 유형이 다르면 동일한 이름을 사용할 수 있습니다. 특정 이름, 마침표가 있는 하나의 전역 루틴에만 대처합니다. 그래서 C 함수 이름을 다음과 같이 간단하게 지정하면 안 됩니다.abs_eq. 일반적으로 다음을 포함하는 것이 좋습니다. C 함수 이름의 데이터 유형 이름과 충돌하지 않도록 다른 데이터 유형에 대한 함수입니다.
셋째, 함수의 Postgres 이름을 만들 수 있었습니다.abs_eq, Postgres를 사용하여 입력 데이터 유형으로 다른 Postgres 함수와 구별 같은 이름의. 예제를 단순하게 유지하기 위해 함수를 만듭니다. C 레벨과 Postgres 레벨에서 동일한 이름을 갖습니다.
마지막으로 이 연산자 함수는 부울값을 반환한다는 점에 유의하세요. 가치. 액세스 방법은 이 사실에 의존합니다. (반면에, 지원 함수는 특정 액세스 방법이 무엇이든 반환합니다. -- 이 경우에는 부호 있는 정수가 필요합니다.) 마지막 루틴은 파일은 우리가 논의할 때 언급한 "지원 루틴"입니다. 의 amsupport 속성pg_am클래스. 우리는 이것을 나중에 사용할 것메이저 토토 사이트. 지금은 무시하세요.
이제 연산자를 정의할 준비가 되었습니다.
연산자 생성 = (
leftarg = 복잡함, rightarg = 복잡함,
절차 = complex_abs_eq,
제한 = eqsel, 조인 = eqjoinsel
)여기서 중요한 것은 절차 이름메이저 토토 사이트(C위에 정의된 함수) 및
제한 및 조인 선택 기능. 당신은 단지
예제에 사용된 선택성 함수(참조복합체.소스). 이런 종류가 있으니 참고하세요
보다 작음, 같음, 보다 큼의 경우에 대한 함수입니다. 이것들
제공되어야 합니다. 그렇지 않으면 옵티마이저가 효과적인 작업을 수행할 수 없습니다.
인덱스를 사용합니다.다음 단계는 이 연산자에 대한 항목을 다음에 추가하는 것입니다.pg_amop관계. 이를 위해서는 다음이 필요합니다.oid연산자 중 우리는 방금 정의되었습니다. 2개를 취하는 모든 연산자의 이름을 찾아보겠습니다.복잡한es, 그리고 우리 것을 선택하세요:
o.oid AS opoid 선택, o.oprname
INTO 테이블 complex_ops_tmp
pg_operator o, pg_type t에서
여기서 o.oprleft = t.oid 및 o.oprright = t.oid
t.typname = '복잡함';
오피이드 | 이름
--------+---------
277963 | +
277970 | <
277971 | <=
277972 | =
277973 | =
277974 |
(6행)(다시 말하지만, 당신 중 일부는oid숫자
거의 확실히 다를 것입니다.) 우리가 운영하는 운영자는
관심 있는 사람은 다음과 같습니다.oids 277970
277974를 통해. 당신이 얻는 값은 아마도 다를 것입니다.
아래 값으로 대체해야 합니다. 우리는 이것을 할 것이다
선택 문으로.이제 업데이트할 준비가 되었습니다.pg_amop와 함께 우리의 새로운 오퍼레이터 클래스. 이 전체에서 가장 중요한 것은 토론은 연산자가 다음보다 작은 것부터 순서가 지정된다는 것입니다. 보다 큼, in을 통해pg_amop. 우리는 추가한다 필요한 인스턴스:
pg_amop에 삽입(amopid, amopclaid, amopopr, amopstrategy)
선택 am.oid, opcl.oid, c.opoid, 1
pg_am am, pg_opclass opcl, complex_ops_tmp c에서
여기서 amname = 'btree' AND
opcname = 'complex_abs_ops' AND
c.oprname = '<';이제 "1"을 대체하는 다른 연산자에 대해 이 작업을 수행하십시오.
위의 세 번째 줄에, 마지막 줄에 "<"가 있습니다. 참고하세요
순서: "보다 작음"은 1, "작거나 같음"은 2, "같음"은 3,
"크거나 같음"은 4이고 "보다 큼"은 5입니다.다음 단계는 "지원 루틴" 등록입니다 이전에 우리의 논의에서 설명한 바와 같습니다.pg_am.oid이것의 지원 루틴은에 저장됩니다.pg_amproc클래스, 액세스 방법으로 키 지정됨oid및 연산자 클래스oid. 먼저, 함수를 등록해야 합니다.포스트그레스(우리가 넣은 것을 기억하세요C이 루틴을 구현하는 코드 연산자를 구현한 파일의 맨 아래 루틴):
CREATE FUNCTION complex_abs_cmp(복합,복잡)
반환 int4
AS 'PGROOT/tutorial/obj/complex.so'
언어 'ㄷ';
SELECT oid, proname FROM pg_proc
WHERE proname = 'complex_abs_cmp';
이드 | 성씨
------+------
277997 | complex_abs_cmp
(1행)(다시 말하지만, 당신의oid번호는
아마도 다를 수 있습니다.) 다음과 같이 새 인스턴스를 추가할 수 있습니다.pg_amproc에 삽입(amid, amopclaid, amproc, amprocnum)
a.oid, b.oid, c.oid, 1 선택
pg_am a, pg_opclass b, pg_proc c에서
여기서 a.amname = 'btree' AND
b.opcname = 'complex_abs_ops' AND
c.proname = 'complex_abs_cmp';
그리고 끝났습니다! (휴.) 이제 생성하고 btree 인덱스 사용복잡한열.