지금까지 설명한 절차를 통해 새 유형을 정의 할 수 있습니다. 새로운 기능과 새로운 운영자. 그러나 우리는 아직 a를 정의 할 수 없습니다 2 차 지수 (예 :B-Tree, r-tree또는 해시 액세스 방법)를 통해 새로운 유형 또는 운영자.
되돌아 보면그림 12-1. 그만큼 오른쪽 절반은 우리가 수정 해야하는 카탈로그를 보여줍니다. 말하다Postgres사용 방법 a 토토 베이가있는 사용자 정의 유형 및/또는 사용자 정의 연산자 (즉.,PG_AM, PG_AMOP, PG_AMPROC, pg_operatorandpg_opclass). 불행히도,이를 수행하라는 간단한 명령은 없습니다. 우리는 할 것입니다 달리기를 통해 이러한 카탈로그를 수정하는 방법을 보여줍니다 예 :에 토토 베이 새로운 운영자 클래스B-Tree저장 및 정렬에 토토 베이 액세스 방법 오름차순 절대 값 순서의 복소수.
thePG_AM테이블에는 하나의 행이 포함되어 있습니다 모든 사용자 정의 액세스 방법. 힙 액세스 지원 메소드가 내장되어 있습니다Postgres, 그러나 다른 모든 액세스 방법은 여기에 설명되어 있습니다. 스키마 이다
표 18-1. 토토 베이 스키마
열 | 설명 |
---|---|
Amname | 액세스 이름 방법 |
Amowner | 소유자의 사용자 ID |
amstrategies | 전략 수 이 액세스 방법 (아래 참조) |
amsupport | 지원 루틴 수 이 액세스 방법 (아래 참조) |
Amorderstrategy | 인덱스가 제공하는 경우 Zero 정렬 순서, 그렇지 않으면 전략의 전략 번호입니다 정렬 순서를 설명하는 연산자 |
AmgetTuple | |
Aminsert | |
... | 절차 식별자 액세스 방법에 토토 베이 인터페이스 루틴. 예를 들어, 열기, 닫히고 행을 얻기위한 레지 프로크 ID 액세스 방법이 여기에 나타납니다. |
the객체 IDPG_AM는 외국 키로 사용됩니다 다른 테이블의. 이 테이블에 새 행을 추가 할 필요는 없습니다. 당신이 관심이있는 것은토토 베이.객체 ID원하는 액세스 방법 행의 연장하다:
PG_AM에서 OID를 선택하여 Amname = 'btree'; OID ----- 403 (1 행)우리는 그것을 사용할 것토토 베이selectat여기서나중에 조항
theAMSTROGRAGES열이 있습니다 데이터 유형에서 비교를 표준화하십시오. 예를 들어,B-Trees는 엄격한 순서를 부과합니다 키, 더 큰 키. 부터Postgres사용자가 정의 할 수 있습니다 운영자,Postgres볼 수 없습니다 연산자의 이름 (예 : ""또는 "<")의 이름으로 일종의 비교토토 베이. 실제로 일부 액세스 방법은 그렇지 않습니다 주문을 전혀 부과합니다. 예를 들어,R-Trees는 사각형 함유를 표현합니다 관계, 해시 데이터 구조는 만 표현합니다 해시 함수의 값에 따른 비트 유사성.Postgres일관성이 필요합니다 쿼리에서 자격을 취하는 방법, 운영자가 사용 가능한 색인이 있는지 결정합니다. 이것은 의미합니다 저것Postgres알아야합니다 예를 들어 "<="및 ""연산자가 A를 파티션하는 것토토 베이.B-Tree. Postgres전략을 사용하여이를 표현합니다 연산자와 사용 할 수있는 방법 간의 관계 스캔 지수.
새로운 전략 세트 정의는 이것의 범위를 벗어납니다. 토론, 그러나 우리는 방법을 설명 할 것입니다B-Tree전략이 필요하기 때문에 작동합니다 새로운 운영자 클래스를 추가하는 것을 알고 있습니다. 에서PG_AM테이블, amstrategies 열은입니다 이 액세스 방법에 정의 된 전략 수. 을 위한B-Trees,이 숫자는 5토토 베이 전략은에 해당합니다.
아이디어는 해당 절차를 추가해야한다는 것토토 베이. 위의 비교와pg_amop관계 (아래 참조). 액세스 방법 코드는이를 사용할 수 있습니다 데이터 유형에 관계없이 전략 번호는 방법을 알아 내기 위해 분할B-Tree, 계산 선택성 등. 추가의 세부 사항에 대해 걱정하지 마십시오 아직 절차; 이 세트가 있어야한다는 것을 이해하십시오. 절차int2, int4, oid,및 a의 다른 모든 데이터 유형B-Tree작동 할 수 있습니다.
때로는 전략이 시스템에 대한 정보가 충분하지 않습니다 인덱스 사용 방법을 알아 내기 위해. 일부 액세스 방법에는 필요합니다 일하기위한 기타 지원 루틴. 예를 들어,B-Tree액세스 방법을 사용할 수 있어야합니다 두 개의 키를 비교하고 하나가 더 큰지를 결정하십시오. 다른 것보다 또는 그 이상. 마찬가지로R-Tree액세스 방법은 계산할 수 있어야합니다 교차로, 노조 및 사각형 크기. 이 작업 SQL 쿼리의 사용자 자격에 해당하지 마십시오. 그들은토토 베이 액세스 방법에서 사용하는 관리 루틴, 내부적.
다양한 지원 루틴을 일관되게 관리하기 위해 전부Postgres액세스 행동 양식,PG_AM라는 열 포함amsupport. 이 칼럼은 액세스 방법에서 사용하는 지원 루틴 수. 을 위한B-Trees,이 숫자는 하나토토 베이 두 개의 키를 가져 와서 -1, 0 또는 +1을 반환하는 일상 첫 번째 키가 두번째.
참고 :엄격히 말하면,이 루틴은 a를 반환 할 수 있습니다 음수 (<0), 0 또는 0이 아닌 양수 ( 0).
theamstrategies입장에서PG_AM는 정의 된 전략의 수입니다 해당 액세스 방법의 경우. 보다 적은 절차 덜 평등하고, 그렇지 않음PG_AM. 비슷하게,amsupport는 지원 루틴의 수입니다 액세스 방법에 필요합니다. 실제 루틴이 나열됩니다 다른 곳.
그건 그렇고,AmorderstrategyEntry는 액세스 방법이 순서 스캔을 지원하는지 여부를 알려줍니다. 영 그렇지 않음을 의미합니다. 그렇다면Amorderstrategy는 전략의 수토토 베이 주문 연산자에 해당하는 루틴. 예를 들어, btree wasAmorderstrategy= 1입니다 "전략 번호보다 작습니다.
다음 관심 표는입니다.pg_opclass. 이 테이블은 연관성에만 존재합니다 운영자 클래스 이름 및 아마도 기본 유형이 운영자 클래스 OID. 기존의 일부 OPClass는토토 베이.int2_ops, int4_ops,andOID_OPS. opclass와 함께 행을 추가해야합니다 이름 (예 :complex_abs_ops) topg_opclass. 그만큼OID이 행의 다른 사람은 외국 키가 될 것토토 베이. 테이블, 특히PG_AMOP.
pg_opclass에 삽입 (opcname, opcdeftype) 'complex_abs_ops', pg_type에서 OID를 선택하십시오. 여기서 typname = 'complex'; OID, OpcName, OpcDeftype를 선택하십시오 pg_opclass에서 여기서 opcname = 'complex_abs_ops'; oid | opcname | opcdeftype --------+---------------------------- 277975 | complex_abs_ops | 277946 (1 행)당신의 OID에 주목하십시오pg_opclass행이 다를 것토토 베이! 걱정하지 마십시오 그래도 이건. 우리는 나중에 시스템 에서이 번호를 얻을 것토토 베이. 우리는 여기에 유형의 Oid를 얻었습니다.
위의 예는이 새로 만들고 싶다고 가정합니다. opclass의 기본 색인 opclass복잡한데이터 유형. 그렇지 않으면 0을 삽입하십시오 안으로opcdeftype, 삽입하기보다는 데이터 유형의 OID :
pg_opclass (opcname, opcdeftype) 값 ( 'complex_abs_ops', 0);에 삽입
이제 액세스 방법과 연산자 클래스가 있습니다. 우리 여전히 일련의 운영자가 필요합니다. 정의 절차 운영자는이 설명서의 앞부분에서 논의되었습니다.complex_abs_ops운영자 클래스 ON btrees, 우리가 필요로하는 운영자는 다음과 같습니다.
절대 값보다 낮습니다 절대 값은 적거나 평등하지 않습니다 절대 값은 동일합니다 절대 값은 평등 한 것보다 더 큰 값입니다 절대 가치보다 큰
정의 된 함수를 구현하는 코드가 IS를 구현한다고 가정하십시오 파일에 저장pgroot/src/튜토리얼/complex.c
C 코드의 일부는 다음과 같습니다. 나머지 예제에 대해 평등 연산자에게 보여줍니다. 그만큼 다른 4 명의 운영자는 매우 유사합니다. 참조complex.c또는Complex.Source자세한 내용은.)
#define mag (c) ((c)- x*(c)- x + (c)- y*(c)- y) 부 complex_abs_eq (complex *a, complex *b) Double Amag = mag (a), bmag = mag (b); return (amag == bmag);
우리는 기능을 다음과 같이 우편으로 알려줍니다.
함수 만들기 complex_abs_eq (complex, complex) Bool을 반환합니다 'pgroot/튜토리얼/obj/complex.so'로 언어 'C';
여기서 일어나고있는 중요한 일이 있습니다.
먼저, 불평등 한 것보다 적은 수준의 운영자는 동등하고, 평등하거나, 평등하며,보다복잡한정의 중토토 베이. 우리는 하나만 가질 수 있습니다 연산자라는 이름의복잡한두 피연산자 모두. 이 경우 우리는 그렇지 않습니다 다른 연산자가 있습니다 = for복잡한, 그러나 우리가 실용적인 데이터 유형을 구축하고 있다면 아마도 원할 것입니다. 복소수에 토토 베이 일반 평등 조작이 되십시오. ~ 안에 이 경우 다른 운영자 이름을 사용해야합니다. complex_abs_eq.
두 번째, 포스트 그레는 운영자가있는 작업자에 대처할 수 있지만 입력 데이터 유형이 다른 한 동일한 이름, C 캔 주어진 이름 인 기간을 가진 하나의 글로벌 루틴에만 대처하십시오. 그래서 우리는 C 기능을 단순한 것과 같은 이름으로 지정해서는 안됩니다abs_eq. 일반적으로 포함하는 것이 좋습니다 충돌하지 않기 때문에 C 함수 이름의 데이터 유형 이름 다른 데이터 유형의 기능으로.
셋째, 기능의 Postgres 이름을 만들 수있었습니다abs_eq, Postgres에 의존합니다 다른 Postgres의 입력 데이터 유형으로 구별하십시오 같은 이름의 기능. 예제를 단순하게 유지하기 위해 우리는 만듭니다 함수의 이름은 C 레벨과 우편둥이에 동일합니다. 수준.
마지막으로,이 연산자 기능은 부울을 반환합니다 값. 액세스 방법은이 사실에 의존합니다. (반면에, 지원 함수는 특정 액세스를 반환합니다 방법은 -이 경우 서명 된 정수입니다.) 최종 파일의 루틴은 우리가 할 때 언급 된 "지원 루틴"입니다. 의 amsupport 열에 대해 논의했습니다PG_AM테이블. 나중에 이것을 사용할 것토토 베이. 지금은 무시하십시오.
이제 우리는 연산자를 정의 할 준비가되었습니다 :
create operator = ( leftarg = complex, rightarg = complex, 절차 = complex_abs_eq, 제한 = eqsel, join = eqjoinsel )여기서 중요한 것은 절차 이름입니다 ( 그만큼C위에서 정의 된 함수) 및 제한 및 결합 선택성 함수. 당신은 그냥 사용해야합니다 예제에 사용 된 선택성 함수 (참조Complex.Source). 다른 것이 있습니다 덜, 평등하고, 더 큰 경우에 토토 베이 기능. 이것들 공급해야합니다. 그렇지 않으면 최적화가 효과적으로 만들 수 없습니다. 색인 사용.
다음 단계는이 연산자에 대한 항목을에 추가하는 것입니다.pg_amop관계. 이렇게하려면 우리는 필요OID한정된. 우리는 모든 운영자의 이름을 찾아 볼 것토토 베이. 둘복잡한es, 그리고 우리를 골라냅니다 :
O.Oid로 Opoid, O.Oprname을 선택하십시오 테이블에 complex_ops_tmp pg_operator o, pg_type t에서 여기서 o.oprleft = t.oid 및 o.oprright = t.oid 및 t.typname = 'complex'; Opoid | oprname --------+------- 277963 | + 277970 | < 277971 | <= 277972 | = 277973 | = 277974 | (6 줄)(다시, 일부OID숫자 거의 확실하게 다를 것입니다.) 우리는 운영자입니다 관심이있는 사람은OIDS 277970 277974를 통해. 당신이 얻는 값은 아마도 다를 것토토 베이. 아래 값으로 대체해야합니다. 우리는 이것을 할 것토토 베이 선정 된 진술과 함께.
이제 우리는 업데이트 할 준비가되었습니다pg_amop새로운 운영자 클래스와 함께. 이것에서 가장 중요한 것 전체 토론은 운영자가 덜 주문된다는 것입니다. 보다 큰 것보다pg_amop. 우리는 필요한 행을 추가합니다 :
pg_amop에 삽입 am.oid, opcl.oid, c.opoid, 1을 선택하십시오 PG_AM AM, PG_OPCLASS OPCL, COMPLED_OPS_TMP C. 여기서 Amname = 'btree'및 opcname = 'complex_abs_ops'및 c.oprname = '<';이제 "1"을 대체하는 다른 연산자를 위해이 작업을 수행합니다. 위의 세 번째 줄과 마지막 줄에서 "<"에서. 참고 주문 : "덜"Is 1, "jec or evel"은 2, "동일"은 3, "크거나 평등"은 4이고 "보다 큰"은 5입니다.
다음 단계는 "지원 루틴"등록입니다. 이전에 우리의 토론에서 묘사PG_AM. 그만큼OID지원 루틴은에 저장됩니다.PG_AMPROC테이블, 액세스 방법에 의해 키워OID및 운영자 클래스OID. 먼저, 우리는에 함수를 등록해야합니다.PostgresC이 루틴을 구현하는 코드 우리가 운영자를 구현 한 파일의 맨 아래에서 루틴) :
함수 만들기 complex_abs_cmp (complex, complex) int4를 반환합니다 'pgroot/튜토리얼/obj/complex.so'로 언어 'c'; PG_PROC에서 OID, Proname을 선택하십시오 여기서 proname = 'complex_abs_cmp'; oid | 프로 이름 --------+------------------ 277997 | complex_abs_cmp (1 행)(다시, 당신의OID번호는 아마도 다를 것입니다.) 우리는 다음과 같이 새 행을 추가 할 수 있습니다 :
pg_amproc에 삽입 (AmopClaid, amproc, amprocnum) A.Oid, B.Oid, C.Oid, 1을 선택하십시오 pg_am a, pg_opclass b, pg_proc c 여기서 a.amname = 'btree'및 b.opcname = 'complex_abs_ops'및 c.proname = 'complex_abs_cmp';
그리고 우리는 끝났습니다! (Whew.) 이제 만들 수 있어야합니다 그리고 btree indexes on 사용복잡한열.