2011-03-13 4 views
1

PostgreSQL을 처음 사용했습니다. 빌드해야하는 하이브리드 데이터베이스에 대한 매우 특이한 요구 사항이 있습니다. 내가 본 모듈에서, 그것은 이 다음과 같이 가능하다는 것을 나에게가 보인다.하이브리드 "인덱스와 같은"btree 구조 - PostgreSQL이이를 수행 할 수 있습니까?

실제로 테이블에 데이터를 추가하지 않고도 인덱스에 key - [values]를 추가 할 수 있어야합니다. 간단히 말해서, 키 - [값] 저장소가 필요합니다. 이상적으로 btree (조회 속도)가 필요합니다. 인덱스 구조가 이상적입니다. 아마도 다른 구조가 이것을 할 것입니다. 나는이 데이터와 색인을 저장하는 오버 헤드를 원하지 않는

KEY  [IDs] 
Blue 10, 20, 23, 47 
Green 5, 12, 40 

:

아주 구체적으로, 내가 좋아하는 뭔가를 저장하고 싶습니다. 데이터를 "인덱싱되었지만 저장되지 않았습니다"라고 말하면됩니다.

이러한 구조를 쿼리하고 데이터 (ID)를 가져올 수 있으며 ID의 INTERSECTS 등 및 키의 IN, BETWEEN, = 등을 수행 할 수있는 능력도 마찬가지로 중요합니다.

아마 짐작할 수 있듯이 최종 목표는 클라이언트의 최종 ID 목록이며 원하는대로 조회합니다.

편집

내가 원하지 않는 것은 모든 값에 대한 키를 기록하는 것입니다. 위의 예를 사용하면 {Blue, 10}, {Blue, 20} 등을 저장하고 싶지 않습니다. {Blue, [10, 20, 23, 47]}를 저장하려고합니다.

전통적인 테이블로 저장하면이 중복 문제를 해결할 방법이 없습니다.

블루 [10, 20, 23, 47]}을 다시 살펴보면 기술적으로는 ID (10, 20, 23, 47)가 값으로 표시된 단일 btree 일뿐입니다. 키 "파란색"이 키로 표시됩니다.

이 데이터 형식이 일치하지 않으면 단일 트리에서 지저분해질 수 있으므로 이상적인 솔루션은 "btree"가 키이고 "btrees"가 각 그룹의 btree 인 btree에서 "btree"입니다. 키 값의

+0

내 의견과 혼동을 줄 수있는 것은 데이터가 내가 말하는 방식대로 작동 할 수 있다고 생각하지 않는다는 것입니다. 기술적으로 내가 여기서 요구하는 것은 각각 btree 값을 갖는 btree 키입니다. 값은 추가 SQL 조작에 참여할 수 있습니다. 원하는 구조는 M/MUMPS와 동일합니다. 덕분에 – IamIC

답변

3

이렇게하면 배열로 값을 저장할 수 있으며, intarray 모듈은 연산자를 조작 할 수있는 모듈을 제공합니다. 즉 : 이상적으로

select unnest(values) from data where key = 'Blue' 
    intersect 
    select unnest(values) from data where key = 'Red'; 

당신이 세트의 int [] 변환 등 교차점을 계산하는 집계 함수를 필요로하지만, 그들은하지 않는 것이와

create table data(key text primary key, values int[] not null); 
insert into data 
    values('Blue', '{10,20,23,47}'),('Green','{5,12,40}'),('Red', '{5,10,28}'); 

당신은 쓸 수 있습니다 제공 될 것입니다.

select key, unnest(values) as value from data; 
    key | value 
-------+------- 
Blue | 10 
Blue | 20 
Blue | 23 
[...] 

는 사실, 당신은 단순히 위의 쿼리로 뷰를 정의 할 수 있습니다 :

정말, 이것은 전형적인 구조의 단지 약간 더 컴팩트하게 수납 할 수 있습니다.지금

create table key_dimension(key_id serial primary key, key text not null unique); 
insert into key_dimension(key) values('Blue'),('Green'),('Red'); 
create table key_value(key_id int not null references key_dimension(key_id), value int not null, primary key(key_id, value)); 
insert into key_value(key_id, value) 
    select key_id, unnest(values) from key_dimension join data using (key); 

과 : 그래서 어떤 쿼리

select value from key_value 
    where key_id = (select key_id from key_dimension where key = 'Red') 
intersect 
select value from key_value 
    where key_id = (select key_id from key_dimension where key = 'Blue') 

키를 선택하는 하나의 값을 연결하는, 하나를 키를 설명하기 위해 :

더 표준화 된 접근 방식은 두 개의 테이블을 가지고하는 것입니다 값은 일련의 키 (key_dimension)에 대해서만 실행해야하며 최소 합성 키 (key_id)는이를 키 값 (key_value)의 실제 데이터 세트로 변환하는 데 사용됩니다.

+0

. 예, 표준화 된 접근 방식을 사용하여 구현할 것입니다. 나는 불충분 한 경험이 없다. 그 성능이 전통적인 "핵심, 가치"패턴을 사용하여이를 저장하고 INTERESCT를 실행하는 것과 어떻게 비교되는지 알고 있습니까? 성능 관점에서 배열을 정렬 된 상태로 유지해야합니까? – IamIC

+1

솔직히 말해서 unnest()를 사용하면 어떤 성능을 얻을지 모르겠지만 ... I/O를 줄이는 것이 가장 중요한 문제라면 실행 가능해야합니다. 구현을 대표 데이터와 비교하는 것은 실제로 대체 할 수 없습니다. – araqnid

+0

감사합니다. 나는이 솔루션이 내 요구에 잘 맞을 것이라고 믿는다. 물론, R & D가있을 것입니다.하지만 필요한 것은 내가 알고있는 것을 다루고 있습니다. – IamIC