문제

어떻게 데이터베이스를 디자인을 지원하는 다음과 같은 태그 지정 기능:

  • 항목이 있을 수 있습의 큰 숫자 태그
  • 검색에 대한 모든 항목은 태그가 가진 주어진 설정의 범주 빨라야 한다(항목이 있어야 모든 범주,그래서 그것은 수색하지,또는-search)
  • 을 만들기/쓰기 항목을 느려질 수 있도록 빠른 검색/독

이상적으로,조회하는 모든 항목은 태그가(적어도)n 어 태그를 수행해야 하나를 사용하여 SQL statement.의 수 있기 때문에 태그를 검색하는 번호뿐만 아니라 태그의 모든 항목에서 알 수없는이 될 수 있습 높은 사용하여 결합하는 것은 비효율적입니다.

어떤 아이디어가?


감사에 대한 모든답니다.

내가 틀리지 않는 경우,그러나,주어 답변을 표시하는 방법 하나 검색에 태그가 있습니다.(모든 항목을 선택하는 것 중 하나 이상을 가지고 있습니다 n 태그).내가 찾는 것은 효율적이고-search.(모든 항목을 선택하는 모든 n 태그와 아마도 더.)

도움이 되었습니까?

해결책

에 대한 ANDing:그것은 당신 같은 소리를 찾고 있다"관계 부문은"작업입니다. 이 문서 다룹 관계 부문에서는 간결하고 아직 세션의 말에 차트 보 방법입니다.

에 대한 성능:비트맵-기반 접근 방법이 직관적으로 소리 같은 것이 상황에 맞게습니다.그러나 저는 확신하지 않는 그것의 좋은 아이디어를 구현하는 비트맵 인덱싱""수동으로,다음과 같 digiguru 는 제안:그 소리는 다음과 같이 복잡한 상황을 할 때마다 새 범주 추가(?) 하지만 일부 DBMSes(Oracle 을 포함하여)제공합 비트맵 인덱스는 어떻게든 사용이 될 수 있기 때문에,내장 인덱스 시스템에서는 잠재적인 복잡성을 인덱스의 유지 관리또한,DBMS 제공하는 비트맵 인덱싱 할 수 있어야에서 그들을 고려한 적절한 경우 수행할 경우 쿼리 계획입니다.

다른 팁

여기에는 좋은 기사에 태그 데이터베이스키:

http://howto.philippkeller.com/2005/04/24/Tags-Database-schemas/

와 함께 성능 테스트:

http://howto.philippkeller.com/2005/06/19/Tagsystems-performance-tests/

참고로 결론이 있는 매우 특정 MySQL,는(적어도 2005 년에 시간에 기록된)아주 가난한 전체 텍스트 색인 특성이 있습니다.

나는 보지 않는 문제가 있는 간단한 솔루션:테이블 항목에 대한 테이블에 대한 태그 crosstable 에 대한"태그"

인덱스에서 크로스 테이블에 충분 최적화할 수도 있습니다.선택하면 해당 항목을 것

SELECT * FROM items WHERE id IN  
    (SELECT DISTINCT item_id FROM item_tag WHERE  
    tag_id = tag1 OR tag_id = tag2 OR ...)  

및 태그 지정될 것입

SELECT * FROM items WHERE  
    EXISTS (SELECT 1 FROM item_tag WHERE id = item_id AND tag_id = tag1)  
    AND EXISTS (SELECT 1 FROM item_tag WHERE id = item_id AND tag_id = tag2)  
    AND ...

은 틀림없이,그래서 효율적인에 대한의 큰 숫자를 비교하는 태그이다.는 경우에 당신을 유지하는 태그의 카운트 메모리에서,당신은 만들 수 있는 쿼리로 시작하지 않은 태그는 종종 그렇게 시퀀스가 평가가 더 빠르다.에 따라 예수의 태그를 일치에 대한 기대와 일치의 모든 단 하나 그들이 확인 될 수 있는 솔루션을 경우,당신은 일치하는 20 태그 및 기대하는 일부를 임의 항목이 일치합니다 그들의 15,다음이 여전히 무거운 데이터베이스에서.

I just wanted 을 강조 표시된 문서는 제프우드의 링크(http://howto.philippkeller.com/2005/04/24/Tags-Database-schemas/ 가)매우 철저한(그것에 대해 설명합의 장점을 3 가지 스키마 접근 방식)과가 좋은 솔루션에 대한 쿼리는 것이 일반적으로 수행보다 더 무엇이었을 여기에 언급된 지금까지(즉그것은 사용하지 않는 상호 연관된 하위에 대한 각 장).또한 많은 좋은 물건입니다.

ps-는 접근 방식 모두가 여기서 얘기가라"Toxi"솔루션에서 문서입니다.

실험할 수 있으로지 엄격하게 데이터베이스 솔루션 자바 콘텐츠 저장소 구현(예: 아파치는 산토끼 한 마리를 들 고)사용하여 검색 엔진 상단에 내장되어의는 다음과 같 아파치 루씬.

이 솔루션은 적합한 캐싱 메커니즘의 가능성은 효율적인 성능보다 가장 솔루션입니다.

그러나 나는 진짜로 생각하지 않는 것에서 작거나 중간 크기의 응용 프로그램을 필요한 것은 더 정교한 구현을 보다 정규화된 데이터베이스에서 언급된 이전 게시물이 있습니다.

편집:과 설명은 매력적인 사용하는 JCR-과 같은 솔루션 검색 엔진입니다.는 것이 크게 단순화하는 프로그램에서 긴 실행됩니다.

가장 쉬운 방법을 만드는 것입 태그 테이블.
Target_Type --경우에 당신은 태그가 여러 테이블
Target --열쇠를 기록되고 있는 태그
Tag --텍스트의 태그

쿼리 데이터를 것 다음과 같습니다.

Select distinct target from tags   
where tag in ([your list of tags to search for here])  
and target_type = [the table you're searching]

업데이트
기반으로 귀하의 요구 사항 및 조건에서,위의 질의 것 같이로

select target
from (
  select target, count(*) cnt 
  from tags   
  where tag in ([your list of tags to search for here])
    and target_type = [the table you're searching]
)
where cnt = [number of tags being searched]

나는 두번째@Zizzencs 제안할 수 있는 것을 원하지 않는 완전히(R)DB 중심

어떻게든 내가 믿는 사용하는 일반 이며 필드를 저장하는 태그의 일부와 함께 적절한 캐/인덱싱을 얻을 수 있습니 더 빠른 결과입니다.하지만 그습니다.

구현했 태그를 사용하는 시스템이 3 테이블을 나타내 많은 관계를 전에(항목을 태그 ItemTags),하지만 난 당신을 다루는 것입니다 태그에서는 많은 장소에,나는 당신을 말할 수 있는 3 테이블을 조작할 수 있/쿼리하는 동시에 모든 시간을 확실히 당신의 코드 더 복잡합니다.

을 고려할 수 있습니다면 복잡성을 추가 가치가있다.

할 수 없을 피하에 참여하고 여전히 다소 정규화됩니다.

나의 접근 방식은 태그 테이블.

 TagId (PK)| TagName (Indexed)

그 후,당신은 TagXREFID 열에 당신의 항목이다.

이 TagXREFID 열 FK 제 3 테이블,나는 그것 TagXREF:

 TagXrefID | ItemID | TagId

그래서 얻을,모든 태그 항목에 대해 같은 것:

SELECT Tags.TagId,Tags.TagName 
     FROM Tags,TagXref 
     WHERE TagXref.TagId = Tags.TagId 
         AND TagXref.ItemID = @ItemID

고 모든 항목에 대한 꼬리표,나는 다음과 같은 코드를 사용하면 됩니다:

SELECT * FROM Items, TagXref
     WHERE TagXref.TagId IN 
          ( SELECT Tags.TagId FROM Tags
                WHERE Tags.TagName = @TagName; )
     AND Items.ItemId = TagXref.ItemId;

하고 무리의 태그 함께,당신은 것을 수정하는 문 위의 약간의 추가 및 태그가 있습니다.TagName=@TagName1 및 태그가 있습니다.TagName=@TagName2...등을 동적으로 만들 쿼리가 있습니다.

가 무엇을 좋아하는 것은 번호를 가지는 테이블의를 나타내는 원시 데이터를,그래서 이 경우에 당신이

Items (ID pk, Name, <properties>)
Tags (ID pk, Name)
TagItems (TagID fk, ItemID fk)

이 작품에 대한 빠른 쓰기 시간,그리고 모든 것을 표준화,그러나 당신은 또한 각 태그,해야 합 가입 테이블은 두 번에 대한 모든 추가하려는 태그를 그리고,그래서 그것을 느리 읽습니다.

개선을 위해 솔루션을 읽을 만드는 것입 캐싱 테이블의 명령을 설정하여 저장 프로시저는 본질적으로 만들 새로운 테이블을 나타내는 데이터에서는 일반 형식으로...

CachedTagItems(ID, Name, <properties>, tag1, tag2, ... tagN)

다음을 고려할 수 있는 방법을 자주 태그 항목 테이블을 요구하는 최신 상태로 유지하는 경우,그것은 모든 삽입,화한 다음 저장된 절차에 따라 커서를 삽입하는 이벤트입니다.의 경우 작업 시간별한 다음,설정 시간별하는 작업이 실행합니다.

이제 정말 영리한 데이터 검색,당신을 만들려고 저장 프로시저를 얻는 데이터에 태그가 있습니다.보를 사용하여 중첩된 쿼리에서 대규모의 경우 성명,전달하고자 하는 하나의 매개 변수를 포함하는 목록의 태그 선택하려는 데이터베이스에서 돌아와 레코드 집합의 항목입니다.이 될 것이 최고의 바이너리 형식을 사용하는 비트 or 연산자입니다.

바이너리 형식,그것은 쉽게 설명해 줍니다.자가 말하는 네 가지 범주에 할당 항목에서는 바이너리를 나타내는

0000

모든 경우에 네 가지 범주에 할당된 개체는 다음과 같이 보일 것이다...

1111

을 경우 첫번째 두...

1100

그것은 그냥 있다고 판단될 경우 바이너리 값을 1 초고 제로에 열을 원합니다.SQL 사용하여 서버의 비트 연산자를 확인할 수 있습니다,거기에서 1 첫 번째 열의를 사용하여 매우 간단한 쿼리를 처리합니다.

이 체크에 대한 링크를 알 more.

역 다른 사람이 무슨 말을 했습니다:트릭에 없 스키마,그것은에 쿼리.

순진한 스키마의 엔티티/레이블/태그는 방법은 바로 갈 수 있습니다.그러나 당신이 볼 수있는,그것의 즉시 명확하지 않을 수행하는 방법과 쿼리와 많은 태그가 있습니다.

를 최적화하는 가장 좋은 방법은 쿼리하는 플랫폼이 될 것입 의존하는,그래서 권하고 싶 다시 태그와 함께 귀하의 질문의와 rdb 를 통해 변화하는 타이틀을"최적의 방법으로 수행하고 쿼리에는 태그 데이터베이스"를 나타냅니다.

나는 몇 가지 제안 MS SQL,하지만 삼가는 경우에는 플랫폼을 사용합니다.

변형은 위의 응답을 tag id,정렬,그들을 결합으로^문자열로 구분하고 해시니다.다음 단순히 연결이 해당 항목입니다.각 조합의 태그를 생산하는 새로운 핵심이다.를 수행하고 간단히 검색을 다시 만들이 있는 해시된 태그 id 를 검색합니다.변화하는 태그 항목에 대한 원인이됩니다 이 해시 다시 만들어집니다.항목과 같은 설정의 범 같은 해시 키입니다.

한 경우에는 배열을 입력할 수 있습 pre-aggregate 필요한 데이터이다.이 대답에서 별도의 thread:

what's 의 유틸리티 배열 형식?

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top