2012-11-07 2 views
1

이 질문은 this one과 비슷하지만 다른 점은 다음과 같습니다. 8 가지 유형의 태그가 있습니다. 이 같은여러 기준을 기반으로 관련 기사 찾기

뭔가 : 나는 어떤을 기반으로 관련 동영상을 선택하려면 하나의 video.id을 감안할 때

videos  [id, title] 
tags1  [id, tag] 
tags2  [id, tag] 
tags3  [id, tag] 
tags4  [id, tag] 
tags5  [id, tag] 
tags6  [id, tag] 
tags7  [id, tag] 
tags8  [id, tag] 
video_tags1 [vid_id, tag_id] 
video_tags2 [vid_id, tag_id] 
video_tags3 [vid_id, tag_id] 
video_tags4 [vid_id, tag_id] 
video_tags5 [vid_id, tag_id] 
video_tags6 [vid_id, tag_id] 
video_tags7 [vid_id, tag_id] 
video_tags8 [vid_id, tag_id] 

공통점이 가장 태그가 있습니다. 나는 서버를 무릎 꿇게하지 않을 방법은 말할 것도없고, 이것을하는 방법을 찾기가 어렵다.

+0

이미 솔루션을 게시했지만 어쩌면 단순화 될 수 있습니다. '꼬리표'는 무엇을 포함합니까? 설명 만? 그래서 어쩌면 나는'tag_id'가 equals인지 검사 할 수 있고'tags' 테이블을 조인 할 필요가 없다. – fthiella

+0

예 태그에 짧은 문자열이 있습니다. 태그 테이블을 조인 할 필요가 없습니다. –

+0

괜찮아, 내 대답을 편집 할게! – fthiella

답변

2

데이터베이스 모델을 변경할 수 있으면 이러한 제안이 적합 할 수 있습니다.

이 방법으로 테이블을 다시 정의 :

videos  [id, title] 
tags [id, tag_type,tag] 
videos_tags [vid_id, tag_id] 

당신은 또한 더 일관성 (8 행, yourtag 유형 각각에 대해 하나를해야합니다)를 tag_type 테이블을 추가 할 수 있습니다.

그런 다음이 쿼리 (그것은 수도 어떤 구문 오류가 있습니다,하지만 내 의도는 당신이 아이디어를 얻을 것입니다) 당신에게 동영상 ID 및 제공하는 하나와 일치하는 태그의 수를 줄 것이다 :

select 
     videos.id, count(videos.id) as nEqualTags 
from 
     videos videos inner join video_tags vtags on (vtags.vid_id=videos.id) 
where 
     vtags.tag_id in (select tag_id from videos_tags where vt.id = ?) 
group by 
     videos.id 
order by 
     nEqualTags desc 

당신을 nEqualTags이 특정 값보다 낮 으면 결과를 줄이기 위해 더 많은 논리를 추가 할 수 있습니다.

(더 나은 성능을 위해 인덱스를 추가하는 것도 좋습니다).

은 내가 정규화 테이블에서 작업하는 것이 좋은 생각

+0

구조를 변경할 수 있습니다. 왜 내가 이걸 시작한다고 생각하지 않았는지 모르겠어 ... 고마워! –

+0

성능에 대한 확신이 없습니다. 마음에 들지 않으면 테스트 할 때 업데이 트하십시오. 궁금 해서요. – richardtz

+0

0.0137s, 359 개의 비디오 레코드 및 1497 개의 비디오 태그 레코드 이전에 가지고 있던 CPU-melting monstrosity보다 훨씬 낫습니다! 감사! –

1

희망이 도움,이 경우이 UNION 쿼리는 도움이 될 수 :

(select 1 as tab, vid_id, tag_id from video_tags1 
union select 2 as tab, vid_id, tag_id from video_tags2 
union select 3 as tab, vid_id, tag_id from video_tags3 
...) 

지금이 같은 쿼리를 사용해야합니다 :

SELECT 
    tags_1.vid_id, count(*) as common_tags 
FROM 
    (big union above) video_tags 
    INNER JOIN 
    (big union above) video_tags_1 
    ON video_tags.tab = video_tags_1.tab 
    AND video_tags.tags_id = video_tags_1.tags_id 
    AND video_tags.vid_id = 1 
    AND video_tags_1.vid_id <> 1 
GROUP BY video_tags_1.vid_id 
ORDER BY common_tags DESC 

이렇게하면 공통된 태그 수만큼 DESC로 정렬 된 모든 레코드가 반환됩니다. 이것은 진행 방법에 대한 아이디어 일 수 있습니다. 동영상 제목을 얻으려면 JOIN을 한 개 더 추가해야합니다. 또한 공통점이있는 태그의 설명을 가져와야하는 경우 ... 가능하지만 쿼리를 많이 복잡하게 만들 것이라고 생각합니다!

데이터베이스 모델을 변경할 수없고 태그 용 테이블과 비디오 태그 용 테이블을 사용할 수 있습니까? 일이 훨씬 쉬워 질 것입니다!

관련 문제