| 포스트그레SQL | ||
|---|---|---|
| 이전 | 다음 | |
지금까지 설명한 절차를 통해 새로운 유형, 함수와 새로운 연산자. 그러나 아직은 정의할 수 없습니다. 보조 인덱스(예: B-트리, R-트리 또는 해시 액세스 스포츠 토토) 새로운 유형이나 그 연산자에 대해.
뒤를 돌아보세요주요 Postgres 시스템 카탈로그. 오른쪽 절반은 다음을 보여줍니다. Postgres에 사용 방법을 알려주기 위해 수정해야 하는 카탈로그 사용자 정의 유형 및/또는 인덱스가 있는 사용자 정의 연산자 (즉,pg_am, pg_amop, pg_amproc그리고pg_opclass). 불행하게도 이를 수행하는 간단한 명령입니다. 우리는 이것을 수정하는 스포츠 토토을 보여줄 것입니다 실행 예제를 통한 카탈로그: 정수를 오름차순 절대값으로 정렬하는 B-트리 액세스 스포츠 토토 값 순서입니다.
그pg_am클래스에는 하나의 인스턴스가 포함되어 있습니다. 모든 사용자 정의 액세스 방법에 대해. 힙 액세스 지원 방법은 Postgres에 내장되어 있지만 다른 모든 액세스 방법은 여기에 설명되어 있습니다. 스키마는
표 35-1. 인덱스 스키마
| 속성 | 설명 |
|---|---|
| amname | 액세스 스포츠 토토 이름 |
| 아소유자 | 소유자의 개체 ID pg_user의 인스턴스 |
| 암킨드 | 현재는 사용되지 않지만 다음으로 설정됨 자리 표시자로 'o' |
| 좋은 전략 | 이를 위한 전략 수 액세스 스포츠 토토(아래 참조) |
| 암지원 | 에 대한 지원 루틴 수 이 액세스 방법(아래 참조) |
| amgettuple aminsert ... | 프로시저 식별자 액세스 스포츠 토토에 대한 인터페이스 루틴입니다. 예를 들어, regproc 인스턴스를 열고 닫고 가져오기 위한 ID 액세스 스포츠 토토이 여기에 표시됩니다. |
인스턴스의 객체 IDpg_am은 다른 많은 클래스에서 외래 키로 사용됩니다. 당신은 필요하지 않습니다 이 클래스에 새 인스턴스를 추가하려면 네가 관심 있는 건 전부야 확장하려는 액세스 메소드 인스턴스의 객체 ID:
pg_am에서 oid 선택 amname = 'btree';
+----+
|로이드 |
+----+
|403 |
+----+
그좋은 전략속성이 다음에 존재합니다. 데이터 유형 전반에 걸쳐 비교를 표준화합니다. 예를 들어, B-트리 작은 것부터 큰 것까지 키에 엄격한 순서를 적용합니다. 포스트그레스 이후 사용자가 연산자를 정의할 수 있도록 허용하지만 Postgres는 연산자 이름(예: "" 또는 "<") 및 어떤 종류인지 알려줍니다. 비교는 그렇죠. 실제로 일부 액세스 방법은 어떠한 요구사항도 부과하지 않습니다. 전혀 주문합니다. 예를 들어, R-트리는 다음을 표현합니다. 직사각형-포함 관계인 반면 해시된 데이터 구조 해시 값을 기반으로 비트 단위 유사성만 표현합니다. 기능. Postgres에는 일관성 있는 방법이 필요합니다. 쿼리에서 자격을 확인하고 연산자를 확인한 다음 사용 가능한 인덱스가 존재하는지 결정합니다. 이는 Postgres가 필요하다는 것을 의미합니다. 예를 들어 "<=" 및 "" 연산자는 B-트리를 분할합니다. Postgres는 전략을 사용하여 이를 표현합니다. 연산자 간의 관계와 연산자를 사용하는 방법 인덱스를 스캔합니다.
새로운 전략 세트를 정의하는 것은 이 범위를 벗어납니다. 하지만 B-트리 전략이 어떻게 작동하는지 설명하겠습니다. 새로운 연산자 클래스를 추가하려면 이를 알아야 합니다. 에서pg_am클래스, amstrategies 속성 이 액세스 방법에 대해 정의된 전략의 수입니다. 에 대한 B-트리, 이 숫자는 5입니다. 이러한 전략은 다음과 같습니다.
표 35-2. B-트리 전략
| 작전 | 색인 |
|---|---|
| 미만 | 1 |
| 작거나 같음 | 2 |
| 같음 | 3 |
| 크거나 같음 | 4 |
| 보다 큼 | 5 |
다음에 해당하는 절차를 추가해야 한다는 생각입니다. 위의 비교는pg_amop관계(아래 참조). 액세스 방법 코드는 이러한 전략을 사용할 수 있습니다 데이터 유형에 관계없이 숫자를 사용하여 분할 방법을 알아보세요. B-트리, 컴퓨팅 선택성 등. 걱정하지 마세요. 아직 절차 추가에 대한 세부 사항은 없습니다. 그냥 거기에 있어야한다는 것을 이해 다음 절차를 따르세요.int2, int4, 이드,및 B-트리가 작동할 수 있는 기타 모든 데이터 유형입니다. 때로는 전략만으로는 시스템이 수행할 수 있는 정보가 충분하지 않습니다. 인덱스를 어떻게 사용하는지 알아보세요. 일부 액세스 방법에는 다른 액세스 방법이 필요합니다. 일하기 위한 루틴을 지원합니다. 예를 들어, B-트리 액세스 메소드는 두 개의 키를 비교하여 하나가 맞는지 결정할 수 있어야 합니다. 다른 것보다 크거나 같거나 작습니다. 마찬가지로, R-트리 액세스 방법은 교차점, 결합체, 그리고 직사각형의 크기. 이러한 작업은 사용자에 해당하지 않습니다 SQL 쿼리의 자격; 그들은 관리 루틴입니다 내부적으로 액세스 방법에서 사용됩니다.
다양한 지원 루틴을 일관되게 관리하기 위해 모든 Postgres 액세스 방법,pg_am이라는 속성을 포함합니다.암지원. 이 속성은 다음에서 사용되는 지원 루틴의 수를 기록합니다. 접근 방법. B-트리의 경우 이 숫자는 1입니다. 두 개의 키를 가져와서 해당 여부에 따라 -1, 0 또는 +1을 반환합니다. 첫 번째 키는 두 번째 키보다 작거나 같거나 큽니다.
참고:엄밀히 말하면 이 루틴은 다음을 반환할 수 있습니다. 음수(< 0), 0 또는 0이 아닌 양수( 0).
그전략pg_am의 항목은 다음과 같습니다. 액세스 방법에 대해 정의된 전략의 수 질문. 작음, 덜 같음 등에 대한 절차는 그렇지 않습니다. 에 나타남pg_am. 마찬가지로,암지원은 단지 지원 루틴의 수입니다 액세스 방법에 따라 필요합니다. 실제 루틴이 나열됩니다. 다른 곳.
다음 관심 클래스는 pg_opclass입니다. 이 클래스만 존재합니다. 이름을 oid와 연결합니다. pg_amop에서 모든 B-트리 연산자 클래스에는 위의 1부터 5까지의 일련의 절차가 있습니다. 일부 기존 opclass는 다음과 같습니다.int2_ops, int4_ops 및 oid_ops. opclass 이름으로 인스턴스를 추가해야 합니다. (예를 들어,complex_abs_ops) ~pg_opclass.oid이 인스턴스의 다른 키는 외래 키입니다. 수업.
INSERT INTO pg_opclass (opcname) VALUES ('complex_abs_ops');
SELECT oid, opc이름
pg_opclass에서
opcname = 'complex_abs_ops';
+------+---------------+
|로이드 | opc이름 |
+------+---------------+
|17314 | int4_abs_ops |
+------+---------------+귀하의 oid에 유의하십시오.pg_opclass인스턴스는 다를 것입니다! 당신은해야
여기에 나타나는 모든 값을 17314로 대체하십시오.
토론.이제 접근 방법과 연산자 클래스가 생겼습니다. 우리는 아직도 일련의 연산자가 필요합니다. 연산자를 정의하는 절차는 다음과 같습니다. 이 설명서의 앞부분에서 논의했습니다. complex_abs_ops 연산자의 경우 Btrees의 클래스에서 필요한 연산자는 다음과 같습니다.
절대값보다 작음
절대값이 작거나 같음
절대값이 같음
절대값 크거나 같음
절대값보다 큼
정의된 함수를 구현하는 코드가 저장되어 있다고 가정합니다. 파일에서PGROOT/src/tutorial/complex.c
코드의 일부는 다음과 같습니다: (우리는 단지 나머지 예제에서는 항등 연산자입니다. 나머지 4개 연산자는 매우 유사합니다. 참조복잡한.c또는복잡한.sql자세한 내용은.)
#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);
몇 가지 중요한 일이 일어나고 있습니다. 아래.
먼저, 작음, 작거나 같음에 대한 연산자에 유의하세요. 같음, 크거나 같음 및 보다 큼int4정의 중입니다. 이들 연산자는 모두 이미 정의됨int4이름 아래 <, <=, =, = 및 . 새로운 운영자는 행동합니다 물론 다르게요. Postgres의 사용을 보장하기 위해 이전 연산자가 아닌 이러한 새 연산자의 이름을 지정해야 합니다. 예전과는 다르게. 이것이 핵심 포인트입니다: 당신은 할 수 있습니다 Postgres의 오버로드 연산자(연산자가 그렇지 않은 경우에만 해당) 인수 유형에 대해 이미 정의되어 있습니다. 즉, < (int4, int4)에 대해 정의된 경우 다시 정의할 수 없습니다. 포스트그레스는 연산자를 정의할 때 이를 확인하지 않으므로 주의하세요. 받는 사람 이 문제를 피하려면 연산자에 이상한 이름이 사용됩니다. 만약에 이것을 잘못 이해하면 액세스 방법이 충돌할 가능성이 높습니다. 스캔을 시도해 보세요.
또 다른 중요한 점은 모든 연산자 기능이 부울 값을 반환합니다. 액세스 방법은 이 사실에 의존합니다. (켜짐 반면에 지원 함수는 무엇이든 반환합니다. 특정 액세스 방법이 필요합니다. 이 경우에는 서명된 정수.) 파일의 마지막 루틴은 "지원 루틴"입니다. 우리가 amsupport 속성을 논의할 때 언급한 바와 같습니다.pg_am클래스. 우리는 이것을 나중에 사용할 것입니다. 지금은 무시하세요.
CREATE FUNCTION complex_abs_eq(복합,복잡)
반환 부울
AS 'PGROOT/tutorial/obj/complex.so'
언어 'c';
이제 이를 사용하는 연산자를 정의하십시오. 언급한 바와 같이, 운영자는 이름은 두 개를 사용하는 모든 연산자 중에서 고유해야 합니다.int4피연산자. 운영자인지 확인하기 위해 아래에 나열된 이름이 사용되었으므로 쿼리를 수행할 수 있습니다.pg_operator:
/*
* 이 쿼리는 정규식 연산자(~)를 사용합니다.
*로 끝나는 세 문자 연산자 이름을 찾으려면
* 캐릭터 &
*/
선택 *
pg_operator에서
WHERE oprname ~ '^..&$'::text;
당신이 원하는 유형에 당신의 이름이 사용되는지 확인하세요. 는 여기서 중요한 것은 절차(C 함수)입니다. 위에 정의됨) 및 제한 및 조인 선택성 기능이 있습니다. 아래에 사용된 것을 사용해야 합니다. 보다 작음, 같음, 보다 큼에 대해 이러한 함수가 다릅니다. 사례. 이를 제공해야 합니다. 그렇지 않으면 다음과 같은 경우 액세스 방법이 중단됩니다. 연산자를 사용하려고 합니다. 다음에 대한 이름을 복사해야 합니다. 제한하고 조인하되, 마지막 단계.
연산자 생성 = (
leftarg = 복잡함, rightarg = 복잡함,
절차 = complex_abs_eq,
제한 = eqsel, 조인 = eqjoinsel
)
5개의 연산자가 작음, 덜 같음, 같음, 더 크거나 더 큰 같음이 정의됩니다.
이제 막 끝났어요. 우리가 마지막으로 해야 할 일은 업데이트하세요pg_amop관계. 이렇게 하려면 다음 속성이 필요합니다.
표 35-3.pg_amproc스키마
| 속성 | 설명 |
|---|---|
| 아모피드 | theoid의pg_amB-트리에 대한 인스턴스(== 403, 위 참조) |
| amopclaid | 그oid의pg_opclass인스턴스 forint4_abs_ops(== 대신에 무엇을 얻었든17314, 위 참조) |
| amopopr | theoid18645_18722 |
| amopselect, amopnpages | 비용 함수 |
그래서 우리는 다음이 필요합니다oid19311_19408int4s, 그리고 우리 것을 선택하세요:
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 = '복잡함';
+------+---------+
|로이드 | 이름 |
+------+---------+
|17321 | < |
+------+---------+
|17322 | <= |
+------+---------+
|17323 | = |
+------+---------+
|17324 | = |
+------+---------+
|17325 | |
+------+---------+(다시 말하지만, 당신의 일부oid숫자
거의 확실히 다를 것입니다.) 우리가 운영하는 운영자는
관심 있는 사람은 다음과 같습니다.oids 17321
17325를 통해 얻을 수 있는 값은 아마도 다를 수 있으며,
아래 값으로 대체해야 합니다. 우리는 다음을 볼 수 있습니다.
연산자 이름을 선택하고 방금 추가한 것을 선택하세요.이제 업데이트할 준비가 되었습니다.pg_amop와 함께 우리의 새로운 오퍼레이터 클래스. 이 전체에서 가장 중요한 것은 토론은 연산자가 덜 평등한 것부터 순서가 지정된다는 것입니다. 더 큰 평등을 통해, inpg_amop. 우리는 추가한다 필요한 인스턴스:
INSERT INTO pg_amop(amopid, amopclaid,
아모포퍼(Amopopr),
amopselect, amopnpages)
선택 am.oid, opcl.oid, c.opoid, 3,
'btreesel'::regproc, 'btreenpage'::regproc
pg_am am, pg_opclass opcl, complex_ops_tmp c에서
WHERE amname = 'btree'
및 opcname = 'complex_abs_ops'
및 c.oprname = '=';순서에 유의하세요: "미만"은 1, "작거나 같음"은 2,
"같음"은 3, "크거나 같음"은 4, "보다 큼"은 3입니다.
5.마지막 단계(드디어!)는 "지원" 등록입니다. 루틴"은 이전에 논의에서 설명한 바와 같습니다.pg_am.oid이것의 지원 루틴은에 저장됩니다.pg_amproc클래스, 액세스 스포츠 토토으로 키 지정됨oid그리고 연산자 클래스oid. 먼저 함수를 등록해야 합니다. Postgres(이를 구현하는 C 코드를 넣었다는 것을 기억하세요) 우리가 구현한 파일의 맨 아래에 있는 루틴 연산자 루틴):
함수 생성 int4_abs_cmp(int4, int4)
반환 int4
AS 'PGROOT/tutorial/obj/complex.so'
언어 'ㄷ';
SELECT oid, proname FROM pg_proc
WHERE prname = 'int4_abs_cmp';
+------+---------------+
|로이드 | 성씨 |
+------+---------------+
|17328 | int4_abs_cmp |
+------+---------------+(다시 말하지만, 당신의oid번호는
아마도 다를 수 있으며 표시되는 값을 대체해야 합니다.
아래 값에 대해.) B-트리 인스턴스의 oid는 다음과 같습니다.
403과 그 것int4_abs_ops17314, 우리는
다음과 같이 새 인스턴스를 추가할 수 있습니다.pg_amproc에 삽입(amid, amopclaid, amproc, amprocnum)
VALUES ('403'::oid, -- btree oid
'17314'::oid, -- pg_opclass 튜플
'17328'::oid, -- 새로운 pg_proc oid
'1'::int2);
| 이전 | 집 | 다음 |
| SQL 확장: 집계 | 위로 | GiST 지수 |