2010-05-21 2 views
23

Related방법 - 예를 들어 SO 사용하여 각

의 장점과 단점, 당신은 그들이 자주 변경 것으로 예상하는 경우 태그를 관리 할 수있는 가장 현명한 방법은 무엇입니까?

방법 1 : 태그는 쉼표로 구분되어 다음

 
table posts 
+--------+-----------------+ 
| postId | tags   | 
+--------+-----------------+ 
| 1 | c++,search,code | 

진심으로 비정규 (쉼표로 구분).

장점 : select 쿼리를 사용하여 태그를 한 번에 가져옵니다. 태그를 업데이트하는 것은 간단합니다. 쉽고 저렴하게 업데이트 할 수 있습니다.

단점 : 태그 검색시 추가 구문 분석, 얼마나 많은 게시물에서 어떤 태그를 사용하는지 계산하기 어렵습니다.

(또는 5 개 태그 같은 것을 제한하는 경우)

 
table posts 
+--------+-------+-------+-------+-------+-------+ 
| postId | tag_1 | tag_2 | tag_3 | tag_4 | tag_5 | 
+--------+-------+-------+-------+-------+-------+ 
| 1 | c++ |search | code |  |  | 

방법 2 : "약간 정상화"(별도의 테이블, 아니 교차로를)

 
table posts 
+--------+-------------------+ 
| postId | title    | 
+--------+-------------------+ 
| 1 | How do u tag?  | 

table taggings 
+--------+---------+ 
| postId | tagName | 
+--------+---------+ 
| 1 | C++  | 
| 1 | search | 

프로 : 쉽게 알 수 태그 수 (count(*) from taggings where tagName='C++').

단점 : 태그 이름은 가능성이 많은, 여러 번 반복됩니다.

방법 3 : (교차로 테이블 정규화) 시원한 아이의

 
table posts 
+--------+---------------------------------------+ 
| postId | title         | 
+--------+---------------------------------------+ 
| 1 | Why is a raven like a writing desk? | 

table tags 
+--------+---------+ 
| tagId | tagName | 
+--------+---------+ 
| 1 | C++  | 
| 2 | search | 
| 3 | foofle | 

table taggings 
+--------+---------+ 
| postId | tagId | 
+--------+---------+ 
| 1 | 1  | 
| 1 | 2  | 
| 1 | 3  | 

프로 :

  • 없음 반복 태그 이름.
  • 더 많은 여자를 좋아합니다.

단점 : 방법 # 1보다 태그를 변경하는 더 비싼.

+0

전 태그를 관리해야했던 사람에게 이메일/트위터를 보냅니다. Jeff Atwood 또는 다른 SO 개발자 중 한 명과 같습니다. 그들은 약간의 통찰력을 줄 수있을 것입니다. –

+6

는 방금 질문에 답변 한 것처럼 들려줍니다. 따라서 귀하의 요구 사항에 가장 적합한 것을 선택하십시오. 여자애들이 너를 좋아하길 원한다면 3 번으로 가라. – mdma

+0

더 많은 소녀들이 당신을 좋아할 것입니까? 나는 그 선택을 좋아한다! – Tarka

답변

23

이 솔루션은 scuttletoxi, mysqlicious이라고합니다.

This article는 장점과 각각의 단점을 비교합니다.

+0

아아, 방금 찾았습니다. 매우 도움이된다! – bobobobo

+0

링크가 끊어진 것 같습니다. – Diederik

+0

@Diederik : 지금보십시오 – Quassnoi

0

나는 개인적으로 솔루션 # 3을 선호.

는 그 솔루션 # 1 mantain에 쉽게 동의하지 않습니다. 태그의 이름을 변경해야하는 상황을 생각해보십시오.

용액 1 :

UPDATE posts SET tag = REPLACE(tag, "oldname", "newname") WHERE tag LIKE("%oldname%") 

솔루션 # 3 :

UPDATE tags SET tag = "newname" WHERE tag = "oldname" 

첫번째 방법이 무겁다.

또한 태그를 삭제할 때 쉼표로 처리해야 (OK, 그것은 쉽게 할 만있어 여전히 그냥 taggings 테이블에 한 줄을 삭제하는 것을 더 어렵게) 솔루션 # 2에 관해서는

입니다 ... 어느 쪽도 없습니다 물고기 나 새

1

나는 세 번째 솔루션의 변형 인 네 번째 해결책이 있다고 주장 할 것이다 : 나는 태그 테이블의 기본 키로 태그 이름을 사용하고

Create Table Posts 
(
    id ... 
    , title ... 
) 
Create Table Tags 
(
    name varchar(30) not null primary key 
    , ... 
) 

Create Table PostTags 
(
    PostId ... 
    , TagName varchar(30) not null 
    , Constraint FK_PostTags_Posts 
     Foreign Key (PostId) 
     References Posts(Id) 
    , Constraint FK_PostTags_Tags 
     Foreign Key (TagName) 
     References Tags(Name) 
     On Update Cascade 
     On Delete Cascade 
) 

알 수 있습니다. 이 방법으로 태그 테이블 자체에 대한 추가 조인없이 특정 태그를 필터링 할 수 있습니다. 또한 태그 이름을 변경하면 PostTags 테이블의 이름이 업데이트됩니다. 드물게 태그 이름을 변경하면 문제가되지 않습니다. 태그 이름을 변경하는 것이 일반적인 경우, 대리 키를 사용하여 태그를 참조하는 세 번째 솔루션으로 이동합니다.

+0

@Thomas : 이것은 "scuttle"과 동일하지만 관리하기가 훨씬 더 어렵습니다. UPDATE 태그를 쓰는 가능성 SET TagName = 'newtag'WHERE TagName = 'oldtag'대신'UPDATE PostTags SET TagName = 'newtag'WHERE TagName = 'oldtag ''은 실제로 가치가 없습니다. – Quassnoi

+0

@Quassnoi - 캐스케이드 업데이트를 사용하면'Update Tags Set Name = 'NewName'Where Name = 'OldName'' 만 써야합니다. 대리 키를 사용하는 경우이를 관리하기가 더 어렵지 않습니다. 진짜 질문은 추가 조인을 피하는 이점이 기존 태그 이름을 변경하는 빈도를 능가하는지 여부입니다. 나중에는 드물기 때문에 성능상의 이점은 아마도 그만한 가치가있을 것입니다. – Thomas

+0

@Thomas : 다시 말해, 목적이없는 여분의 테이블 ('Tags')을 가지고있는 것을 제외하고는 way 2 ('scuttle')와 어떻게 다른가요? – Quassnoi

0

SO가 해결책 # 1을 사용한다고 생각합니다. # 1 또는 # 3 중 하나와 함께 갈 것입니다.

태그를 추가 할 수있는 몇 가지 사항 (예 : 게시물과 제품 모두에 태그를 추가하는 경우)을 고려해야합니다. 이는 데이터베이스 솔루션에 영향을 줄 수 있습니다.

0

글쎄 내 웹 사이트에 대한 세 번째 솔루션을 채택한 것과 같은 의문을 가지고 있습니다. 이 방법으로 행을 열로 사용하는 가변 길이 튜플의 문제를 해결할 다른 방법이 있다는 것을 알고 있습니다. 튜플 환원자를 식별하는 정보와 각 행마다 하나씩 구성된 다양한 정보가 있습니다.

+--------+-------+-------------------------------------+ 
| postId | label | value        | 
+--------+-------+-------------------------------------+ 
| 1 | tag |C++         | 
+--------+-------+-------------------------------------+ 
| 1 | tag |search        | 
+--------+-------+-------------------------------------+ 
| 1 | tag |code         | 
+--------+-------+-------------------------------------+ 
| 1 | title | Why is a raven like a writing desk? | 
+--------+-------+-------------------------------------+ 

이것은 실제로 나쁘지만 때로는 유일한 실현 가능한 해결책이며, 관계형 접근 방법과는 거리가 있습니다.

+0

이지만 아직 업데이트 및 유지 관리가 쉽고 쿼리가 느려지지만 3 가지 테이블에서 거대한 수의 튜플을 조인 할 때 같은 시간 문제가 발생할 수 있습니다. 다른 인덱스를 사용하는 것을 고려할 수 있습니다 특정 유형의 쿼리의 성능을 향상시킵니다. 이 도움이되기를 바랍니다. – urobo