집합 기반 태그 시스템 설계

문서 개요

심심풀이로 만드는 미디어 검색 시스템은 태그 기반으로 미디어를 분류한다. 다만 기존의 태그라는 개념을 그대로 사용할 경우 몇가지 문제점이 있어서 새로운 태그 시스템에 대해서 구상해보았다. 아래의 내용은 기존의 태그 시스템에 대한 기본적인 이해가 있다고 가정하고 기존의 시스템의 몇가지 문제와 그것의 해결법 및 구현 예제이다

기존의 태그 시스템으로 미디어 관리할 경우 발생하는 문제점

하나의 개념, 여러개의 태그

예를 들어 요스가노소라 애니메이션 파일이 있다고 치자. 사용자는 여기에 태그를 ‘yosugano sora’라고 쓸수도 있고 ‘yosuga no sora’라고쓸수도 있고 ‘요스가노소라’라고 쓸수도 있다. 그렇게 되면 파일하나에 태그가 3개가 붙게 된다. 하지만 3개의 태그는 실제로는 하나의 개념을 지칭한다. 위와 같이 동일한 개념의 태그라고 하더라도 한글/영어 표기법이나 띄어쓰기, 특수문자등에 의해서 서로 다르게 표기할수있다.

하나의 개념, 다른 검색결과

요스가노 소라 1화에는 ‘yosugano sora’라는 태그를 붙였다. 2화에는 ‘요스가노소라’라는 태그를 붙였다. ‘yosugano sora’로 검색할때와 ‘요스가노소라’로 검색하면 서로 다른 결과가 나오게된다. 하지만 유저가 의도한 것은 어떤 태그로 검색하든지간에 같은 결과가 나오는 것이다.

집합 기반 태그 시스템 개요

기본적이 개념은 기존의 태그 시스템과 동일하다. 추가되는 사항은 서로 다른 태그를 집합으로 묶어서 같은것으로 취급할수 있다는 것이다. 위의 예를 다시 갖다쓰면, 요스가노소라 1화에는 ‘yosugano sora’라는 태그를 달았다. 2화에는 ‘요스가노소라’라는 태그를 달았다. 그리고 ‘yosugano sora’와 ‘요스가노소라’를 같은 태그 집합으로 묶는다. 검색을 하게되면 2개중 어떤태그로 검색을 한다고 하더라도 같은 태그 집합에 있는 태그의 목록까지 동시에 검색해서 보여준다. 이렇게 하면 어떤 태그로 검색해도 같은 검색결과를 보여줄수 있다.

구현 기본 설계

집합 기반 태그 시스템을 위해서 테이블 2개가 필요하다

uuid - tag table

기존의 태그 시스템을 구현하는 것과 비슷한 방법이다

  • uuid | tag_id
  • asdf | 3
  • dfsf | 4
  • 348f | 2

tag는 태그 이름 자체를 저장하지않고 tag set table에서 검색가능한 태그의 uid를 사용한다. 이떄 주의할점은 yosugano sora와 요스가노소라는 같은 태그집합에 속하지만 서로 다른 다른 태그이므로 tag id는 달라야한다. 다른 tag에 대해서 tag id를 다르게 유지함으로써 tag간의 집합 통합과 분리를 가능하게 했다.(집합의 통합/분리는 아래에 추가 설명)

uuid 부분은 어떤것에 태그를 다는가에 따라서 알아서 쓰면 될것이다. 블로그면 글번호라든가 위키면 페이지 번호라든가 스토리지면 파일명이라든가… 참고로 해당 프로젝트에서는 파일을 기반으로 생성되는 40글자 해시를 uuid로써 사용한다

tag set table

  • tag_id | tag_name | root_tag
  • 1 | yosugano sora | 1
  • 2 | 요스가노 소라 | 1
  • 3 | 포니 | 3

root_tag가 같은것은 같은 태그 그룹에 속한다. tag id와 root tag는 foreign key의 관계라고 보면 된다. 태그를 처음 만들때마가 tag id는 고유하게 생성되고 생성된 root tag와 tag id는 동일하다.

태그 집합이라고 했지만 진짜 집합과는 달리, 대표 태그라는게 존재한다. 대표 태그가 root tag가 된다. 태그 집합을 외부로 보여줄때 사용할 이름이라든가 태그집합의 고유 id로써 사용된다.

태그를 통합할때는 루트밑으로 들어갈 태그의 root tag를 루트의 root tag로 바꿔주면 된다. 반대로 태그를 집합에서 제거할때는 tag id의값을 root tag에 써주면 된다.

이제 남은건 적절히 잘 구현하면 된다. 이것을 적용한 블로그 엔진을 만들어볼까 햇으나 귀찮아서 결국 하지 않았다. 나중에 다시 꺼내볼수 있을까…


comments powered by Disqus