효율적인 태그 기반 조회를 허용하는 데이터 구조


11

다음과 유사한 데이터 저장을위한 매우 효율적인 데이터 구조를 찾고 있습니다.

ID 태그 주문 1 주문 2 
--------------------------
1 1,2 1 1
2 2,5 2 3
3 1,7 4 7
4 6 3 0

그것은 나에게 태그의 표현을 포함하는 모든 ID의 목록을 제공한다고 나는 그런 방식으로이 구조를 조회 할 수 있어야합니다 - 지원 ANDORNOT운영. 예 : ((1 또는 2), 7 아님)

또한 결과 순서 (Order1 또는 Order2)를 지정하고 선택적 오프셋으로 반환되는 최대 행을 지정할 수 있어야합니다. 처음 30-100 개의 결과를 가져 오는 성능이 핵심입니다.

마지막으로, "태그 관계"를 찾는 저렴한 방법이 필요합니다. 예를 들어 어떤 태그가 태그 (1 OR 2)와 어떤 관련이 있고 어떤 빈도에 있는지 알고 싶습니다. 빈도별로 정렬 된 1 OR 2와 동일한 세트에 어떤 태그가 나타나는지 의미합니다.

이러한 종류의 작업에 어떤 데이터 구조 (또는 구조 세트)가 매우 효율적 일지 알고 있습니까?

(이 사이트를 SE 사이트 사이트 의 태그가 지정된 페이지 를 다시 디자인하기위한 개념 증명으로 사용하고 싶습니다 )


1
그냥 의견 (아마도 사소한). 관계형 데이터베이스 관리 시스템에 의존하지 않는 이유는 무엇입니까? <id, tag> 쌍으로 테이블을 정의하고 태그 열에 색인을 추가 할 수 있습니다. 그런 다음 표준 SQL 쿼리를 사용하여 데이터를 추출 할 수 있습니다. RDBMS는 쿼리 최적화 및 출력 정렬의 "더러운"작업을 효율적으로 수행합니다.
Marzio De Biasi

@Vor, 표현은 엄청나게 비효율적이며, 자체 조인은 악의적 인 쿼리가됩니다.
Sam Saffron

@ 샘 : 알겠습니다. 귀하의 작업은 매우 일반적이므로 데이터 마이닝 도구가있는 우수한 RDBMS가 작업을 수행 할 수 있다고 생각했습니다. 나는 바닥을 데이터 구조 전문가에게 맡긴다. :-)
Marzio De Biasi

AND, OR, NOT의 모든 조합을 허용하면 모든 항목을 나열하지 않는 데이터 구조를 만드는 것이 어려워집니다 (아마 3-CNF로 제한 될 수 있습니까?). 이러한 제한이 없으면 태그 요구 사항을 통과하는 30-100을 찾을 때까지 레코드를 지정된 순서대로 실행하십시오. 일반적으로 Vor가 데이터베이스를 사용하여 많은 노력을 기울이겠다고 제안한 것에 동의합니다.
bbejot

전문가는 아니지만 태그에 대해 물어볼 수있는 방법에 제한을 두지 않으면 어려울 것이라고 생각합니다. 그것들을 CNF로 제한하는 것은 (비교가 제안한 바와 같이), 다른 방법은 쿼리가 요청할 수있는 다른 태그의 수를 작은 수로 제한하는 것입니다 (예 : 6).
Kaveh

답변:


6

이것은 효율적인 데이터 구조에 대한 정확한 대답이 아니라 @bbejot와 @Kaveh의 의견에 대한 정교한 설명으로 현재 질문이 주어진 이유에 대해 손을 흔들며 논쟁하는 이유는 무엇입니까? 전체 데이터베이스. 논쟁은 SAT의 감소, 지수 시간 가설 및 많은 손짓에 기초합니다.

최대 서로 다른 태그 가 있다고 가정 하면 각 id 는 길이 의 비트 벡터 와 연관된 것으로 생각할 수 있습니다. 여기서 -th 태그 가 있으면 이고 , 그렇지 않으면 입니다. 데이터베이스 외모가 좋아에 대한 실질적인 제한이 없기 때문에, 나는 그것이 ID를 가지고 가정 할 수있다 을 통해 와 번째 ID가의 관련 태그 벡터를 갖는 바이너리로 작성합니다. 순서 필드는 문제를 더욱 어렵게 만들기 때문에 임의적 일 수 있습니다. 이제 , 및 대한 임의 쿼리가 제공되면nx|x|=nxj=1jxj=012nkkANDORNOT그러면 변수 에 대해 SAT 질문을 합니다. 지수 시간 가설에 따르면, 이것은 보다 훨씬 빠를 것으로 예상 할 수 없습니다n2n 것으로 기대할 수 없습니다. 즉, 전체 데이터베이스를 검색하는 것보다 훨씬 빠를 것으로 기대할 수 없습니다.

쿼리 길이를 효율적으로 검색하지 않아야합니다 (SAT로 축소). 또한 지수 시간 가설로 데이터베이스의 모든 항목을 보는 것보다 훨씬 나을 것으로 기 대해서는 안됩니다.

n1


좋은 관찰. 각 질문에는 최대 5 개의 태그가 있으므로 태그에 대한 쿼리는 5-CNF와 같습니다.
Kaveh

감사합니다! 예, 여기서 5-CNF를 더 가정 할 수 있습니다. 태깅 동작은 무작위가 아닙니다. 일반적으로 사람들은 가장 일반적인 태그로 물건에 태그를 지정하므로 몇 가지 다른 단축키를 사용할 수 있습니다.
Sam Saffron

1
@Kaveh, 우리는 결국 메모리 구조를 굴 렸습니다. 몇 가지 사소한 단축키가 있으며 정렬은 병목 현상이며 힙 정렬을 사용하거나 수정 된 빠른 정렬을 사용하면 전체 정렬을 수행하지 않고도 효율적으로 상위 N을 선택할 수 있습니다. 사전 계산 정렬을 사용하면 피벗을보다 효율적으로 선택하고 전체 스캔이 필요할 때 정렬을 피할 수 있습니다. 멀티 스레딩은 선택 속도를 높입니다. 사용자가 구조와 상호 작용하기 전에 많은 작업이 백그라운드로 지연 될 수 있습니다. 놀랍게도 우리의 인 메모리 구조는 스택 오버플로 데이터 세트를 검색하기 위해 평균 0ms입니다.
Sam Saffron

@SamSaffron-이 기능을 자세히 설명하는 MSO 게시물은 어디에 있습니까? 여기에 버그 보고서가 있습니다 .
케빈 베르메르

5

이것은 매우 간단한 대답이지만 효과적이라고 생각합니다.

Map Tag ([Id],[Id])O(log(n))

Map Id (Set Tag)IdO(nlog(m))


여러 번 스풀링 된 맵과 같은 매우 간단한 구조가 여기에가는 가장 좋은 방법 일 수 있다는 데 동의하는 경향이 있습니다. 메모리가 저렴하고 여러 캐시를 유지 관리하는 것은 그리 어렵지 않습니다
Sam Saffron
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.