F.18. intarray

F.18.1. intarray 함수와 연산자들
F.18.2. 인덱스 지원
F.18.3. 사용 예
F.18.4. 성능 검사
F.18.5. 만든이

intarray 모듈은 정수를 구성 요소로 하는 null 값이 없는 배열 처리를 위한 유용한 함수와 연산자를 제공한다. 또한 이 배열 자료형에 대한 인덱스 검색 기능도 제공한다.

This module is considered trusted, that is, it can be installed by non-superusers who have CREATE privilege on the current database.

여기서 소개하는 모든 연산자는 그 대상 배열에 null 값이 있으면, 오류를 낸다.

여기서 소개하는 대부분의 연산자는 일차원 배열에서만 쓸모가 있다. 물론 다차원 배열에서도 사용 가능 하지만, 그 자료는 저장 순서를 기반으로 일차원 배열처럼 간주한다.

F.18.1. intarray 함수와 연산자들

intarray 모듈에서 제공하는 함수는 표 F.9에서, 연산자는 표 F.10에서 소개한다.

표 F.9. intarray 함수들

함수

설명

예제

icount ( integer[] ) → integer

배열 요소 개수

icount('{1,2,3}'::integer[])3

sort ( integer[], dir text ) → integer[]

배열 오름,내림차순 정렬. dir에는 asc 또는 desc만 허용

sort('{1,3,2}'::integer[], 'desc'){3,2,1}

sort ( integer[] ) → integer[]

sort_asc ( integer[] ) → integer[]

오름차순 정렬

sort(array[11,77,44]){11,44,77}

sort_desc ( integer[] ) → integer[]

내림차순 정렬

sort_desc(array[11,77,44]){77,44,11}

uniq ( integer[] ) → integer[]

중복된 요소 제거

uniq(sort('{1,2,3,2,1}'::integer[])){1,2,3}

idx ( integer[], item integer ) → integer

해당 item 요소가 배열의 몇번째에 있는지 (0이면 없음)

idx(array[11,22,33,22,11], 22)2

subarray ( integer[], start integer, len integer ) → integer[]

배열의 start 시작 위치에서, len 개수 만큼 부분 배열 추출

subarray('{1,2,3,2,1}'::integer[], 2, 3){2,3,2}

subarray ( integer[], start integer ) → integer[]

배열의 start 번째부터 시작해서 끝까지 부분 배열 추출

subarray('{1,2,3,2,1}'::integer[], 2){2,3,2,1}

intset ( integer ) → integer[]

입련 인자를 단일 요소로 하는 배열 반환

intset(42){42}


표 F.10. intarray 연산자들

연산자

설명

integer[] && integer[]boolean

겹침 — 두 배열 요수 가운데 한 요소라도 같으면 true

integer[] @> integer[]boolean

포함함 — 왼쪽 배열이 오른쪽 배열을 포함하면 true

integer[] <@ integer[]boolean

포함됨 — 왼쪽 배열이 오른쪽 배열에 포함되면 true

# integer[]integer

배열 요소 수

integer[] # integerinteger

idx 함수의 연산자

integer[] + integerinteger[]

배열에 요소 추가 (배열 마지막에 추가됨)

integer[] + integer[]integer[]

배열 합치기, 왼쪽 오른쪽 순서대로 합침

integer[] - integerinteger[]

오른쪽에 지정한 정수가 배열 요소에 있으면 뺌

integer[] - integer[]integer[]

왼쪽 배열에서 오른쪽 배열 요소들을 모두 뺌

integer[] | integerinteger[]

오른쪽 정수를 왼쪽 배열에 포함함 (이미 있으면 무시)

integer[] | integer[]integer[]

두 배열을 합치면서 겹치는 것 없앰

integer[] & integer[]integer[]

두 배열의 교집합

integer[] @@ query_intboolean

해당 query_int 조건에 맞으면 true (아래 참조)

query_int ~~ integer[]boolean

@@ 연산자의 교환 연산자


(8.2 이전 버전에서는 @> 연산자와 <@ 연산자는 각각 @, ~ 로 사용했었다. 이 연산자들도 아직 사용할 수는 있지만, 범용 배열 연산자들이 정리되면서 이 연산자(@,~)는 이제 더 이상 사용하지 않는다. 이 연산자들은 기본 지리정보 자료형에서 아직 사용하기에, 헷갈리지 않기 바란다!)

&&, @>, <@ 연산자는 범용 배열 자료형의 기본 연산자로 채택되어 그 사용법이 똑같다. 다른 점은 이 모듈을 사용하면, 정수형 배열에서는 null 값이 없어야되고, 그 외 배열 자료형에서는 null 값이 있어도 된다. 이런 제한은 정수형 배열 자료형에서 처리 속도를 빠르게 하기 때문에, 아직까지 이런 차이가 있다.

@@, ~~ 연산자는 지정한 쿼리 조건에 만족하는가를 검사하는 연산자다. 이 쿼리는 문자열로 query_int 구문을 사용해야 하면, 사용할 수 있는 기호는 & (AND), | (OR), ! (NOT) 이다. 예를 들어 이 쿼리가 1&(2|3) 이라면, 해당 배열 요소들 가운데, 1은 반드시 있어야 하고, 2 또는 3도 반드시 있는 배열이면 이 연산자는 true를 반환한다.

F.18.2. 인덱스 지원

intarray 모듈은 &&, @>, <@, @@ 연산자를 사용할 경우 인덱스를 사용해서 보다 빠르게 그 결과를 확인할 수 있도록 연산자 클래스를 제공한다.

GiST 색인 방법으로 다음 두 가지 인자를 추가할 수 있는 연산자 클래스를 제공한다: gist__int_ops (기본값) 클래스는 4바이트 정수 최대값 만큼의 배열 요소가 있는 경우, gist__intbig_ops 클래스는 8바이트 정수 최대값 만큼의 배열 요소가 있는 경우에 사용한다. 이 색인 방법은 RD-tree 자료 구조에 대한 구현체이며, 내장된 압축이 별로 안되는 방법이다.

gist__int_ops approximates an integer set as an array of integer ranges. Its optional integer parameter numranges determines the maximum number of ranges in one index key. The default value of numranges is 100. Valid values are between 1 and 253. Using larger arrays as GiST index keys leads to a more precise search (scanning a smaller fraction of the index and fewer heap pages), at the cost of a larger index.

gist__intbig_ops approximates an integer set as a bitmap signature. Its optional integer parameter siglen determines the signature length in bytes. The default signature length is 16 bytes. Valid values of signature length are between 1 and 2024 bytes. Longer signatures lead to a more precise search (scanning a smaller fraction of the index and fewer heap pages), at the cost of a larger index.

GIN 연산자 클래스로 gin__int_ops 연산자 클래스도 제공한다.

해당 배열형에 대해서 GiST 색인 방법을 쓸지, GIN 색인 방법을 쓸지에 대해서는 Gist, GIN 인덱스의 장단점을 충분히 파악한 후 선택하면 된다.

F.18.3. 사용 예

-- 하나의 메시지는 하나 또는 여러 섹션을 포함한다.
CREATE TABLE message (mid INT PRIMARY KEY, sections INT[], ...);

-- sections 칼럼의 자료 길이를 32 바이트로 제한한 인덱스
CREATE INDEX message_rdtree_idx ON message USING GIST (sections gist__int_ops(siglen=32));

-- 겹침 연산자를 이용한 해당 섹션이 있는 메시지 찾기
SELECT message.mid FROM message WHERE message.sections && '{1,2}';

-- 포함 연산자를 이용한 해당 섹션이 있는 메시지 찾기
SELECT message.mid FROM message WHERE message.sections @> '{1,2}';

-- 윗 쿼리와 같은 쿼리 문자열을 이용한 또 다른 방법
SELECT message.mid FROM message WHERE message.sections @@ '1&2'::query_int;

F.18.4. 성능 검사

소스 디렉터리 안 contrib/intarray/bench 디렉터리에 이 모듈에 대한 성능 검사 관련 소스들이 포함되어 있다. (DBD::Pg perl 모듈이 먼저 설치되어 있어야 한다) 사용법:

cd .../contrib/intarray/bench
createdb TEST
sql -c "CREATE EXTENSION intarray" TEST
./create_test.pl | psql TEST
./bench.pl

bench.pl 스크립트는 다양한 옵션을 제공한다. 옵션 설명은 아무런 옵션 없이 실행하면 보여준다.

F.18.5. 만든이

모든 작업은 Teodor Sigaev ()와 Oleg Bartunov ()가 했다. 추가적인 정보는 http://www.sai.msu.su/~megera/postgres/gist/ 페이지에서 제공한다. Andrey Oktyabrski가 새 함수와 연산자들 추가 작업을 했다.