문제

태그 지정을 구현하는 몇 가지 방법에 대해 들었습니다.TagID와 ItemID 사이의 매핑 테이블 사용(나에게는 이해가 되지만 확장 가능합니까?), ItemID에 고정된 수의 가능한 TagID 열 추가(나쁜 생각인 것 같습니다), 쉼표로 구분된 텍스트 열에 태그 유지(소리 미쳤지 만 작동 할 수 있습니다).누군가 희소 행렬을 추천한다는 이야기도 들었습니다. 그런데 태그 이름이 어떻게 우아하게 커지나요?

태그에 대한 모범 사례가 누락되었나요?

도움이 되었습니까?

해결책

적절하게 인덱싱되고 적절한 데이터베이스에서 실행되는 외래 키가 있는 세 개의 테이블(하나는 모든 항목 저장용, 하나는 모든 태그용, 하나는 둘 사이의 관계용)이 제대로 작동하고 적절하게 확장되어야 합니다.

Table: Item
Columns: ItemID, Title, Content

Table: Tag
Columns: TagID, Title

Table: ItemTag
Columns: ItemID, TagID

다른 팁

일반적으로 나는 Yaakov Ellis의 의견에 동의하지만 이 특별한 경우에는 또 다른 실행 가능한 솔루션이 있습니다.

두 개의 테이블을 사용하십시오.

Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID

Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title

여기에는 몇 가지 주요 이점이 있습니다.

먼저 개발이 훨씬 간단해집니다.삽입 및 업데이트를 위한 3테이블 솔루션 item 당신은 검색해야 Tag 테이블에 이미 항목이 있는지 확인하세요.그런 다음 새로운 것과 합류해야합니다.이것은 결코 사소한 일이 아닙니다.

그러면 쿼리가 더 간단해지고 빨라질 수도 있습니다.수행할 세 가지 주요 데이터베이스 쿼리는 다음과 같습니다.모두 출력 Tags 하나를 위해 Item, 태그 클라우드를 그리고 하나의 태그 제목에 대한 모든 항목을 선택합니다.

하나의 항목에 대한 모든 태그:

3-테이블:

SELECT Tag.Title 
  FROM Tag 
  JOIN ItemTag ON Tag.TagID = ItemTag.TagID
 WHERE ItemTag.ItemID = :id

2-테이블:

SELECT Tag.Title
FROM Tag
WHERE Tag.ItemID = :id

태그 클라우드:

3-테이블:

SELECT Tag.Title, count(*)
  FROM Tag
  JOIN ItemTag ON Tag.TagID = ItemTag.TagID
 GROUP BY Tag.Title

2-테이블:

SELECT Tag.Title, count(*)
  FROM Tag
 GROUP BY Tag.Title

하나의 태그에 대한 항목:

3-테이블:

SELECT Item.*
  FROM Item
  JOIN ItemTag ON Item.ItemID = ItemTag.ItemID
  JOIN Tag ON ItemTag.TagID = Tag.TagID
 WHERE Tag.Title = :title

2-테이블:

SELECT Item.*
  FROM Item
  JOIN Tag ON Item.ItemID = Tag.ItemID
 WHERE Tag.Title = :title

그러나 몇 가지 단점도 있습니다.데이터베이스에서 더 많은 공간을 차지할 수 있으며(더 많은 디스크 작업으로 인해 속도가 느려질 수 있음) 정규화되지 않아 불일치가 발생할 수 있습니다.

태그의 특성상 일반적으로 매우 작기 때문에 크기 증가가 크지 않기 때문에 크기 논쟁은 그다지 강력하지 않습니다.태그 제목에 대한 쿼리는 각 태그를 한 번만 포함하는 작은 테이블에서 훨씬 빠르다고 주장할 수 있으며 이는 확실히 사실입니다.그러나 가입하지 않고도 절약할 수 있는 비용과 이에 대한 좋은 인덱스를 구축할 수 있다는 사실을 고려하면 이를 쉽게 보상할 수 있습니다.물론 이는 사용 중인 데이터베이스의 크기에 따라 크게 달라집니다.

불일치 주장도 약간의 논란이 있습니다.태그는 자유 텍스트 필드이며 '모든 태그 이름을 "foo"에서 "bar"로 변경'과 같은 예상되는 작업은 없습니다.

그래서 tldr :나는 2 테이블 솔루션을 선택하겠습니다.(사실 갈 예정이에요.이에 반대하는 타당한 주장이 있는지 확인하기 위해 이 기사를 찾았습니다.)

Couchdb와 같이 map-reduce를 지원하는 데이터베이스를 사용하는 경우 일반 텍스트 필드나 목록 필드에 태그를 저장하는 것이 실제로 가장 좋은 방법입니다.예:

tagcloud: {
  map: function(doc){ 
    for(tag in doc.tags){ 
      emit(doc.tags[tag],1) 
    }
  }
  reduce: function(keys,values){
    return values.length
  }
}

group=true로 실행하면 결과가 태그 이름별로 그룹화되고 태그가 발생한 횟수도 반환됩니다.그것은 매우 유사하다 텍스트에서 단어의 발생 횟수 세기.

태그를 저장하기 위해 단일 형식의 텍스트 열[1]을 사용하고 이를 색인화하기 위해 가능한 전체 텍스트 검색 엔진을 사용합니다.그렇지 않으면 부울 쿼리를 구현하려고 할 때 크기 조정 문제가 발생합니다.

보유하고 있는 태그에 대한 세부 정보가 필요한 경우 증분적으로 유지 관리되는 테이블에서 이를 추적하거나 일괄 작업을 실행하여 정보를 추출할 수 있습니다.

[1] 일부 RDBMS는 구문 분석 단계가 필요하지 않아 저장에 더 적합할 수 있지만 전체 텍스트 검색에 문제를 일으킬 수 있는 기본 배열 유형을 제공하기도 합니다.

저는 항상 태그를 별도의 테이블에 보관하고 매핑 테이블을 사용했습니다.물론 나도 정말 큰 규모로 어떤 일을 해본 적이 없다.

"태그" 테이블과 맵 테이블이 있으면 태그 클라우드를 생성하는 것이 매우 간단해집니다. SQL을 쉽게 결합하여 각 태그가 사용되는 빈도를 계산한 태그 목록을 얻을 수 있기 때문입니다.

나는 다음과 같은 디자인을 제안합니다 :품목 테이블:항목 ID, 태그 목록1, 태그 목록2
이는 속도가 빠르고 항목 수준에서 데이터를 쉽게 저장하고 검색할 수 있게 해줍니다.

병렬로 다른 테이블을 빌드합니다.태그 태그는 태그 고유 식별자를 만들지 않으며 두 번째 열에서 공간이 부족한 경우 100 개 항목이 다른 행을 생성한다고 가정합니다.

이제 태그에 대한 항목을 검색하는 것이 매우 빨라질 것입니다.

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