태그 또는 태그 부착에 권장되는 SQL 데이터베이스 설계
TagID와 Item 사이의 매핑 테이블을 사용하여 태그를 구현하는 몇 가지 방법에 대해 들은 적이 있습니다.ID(제게는 이해가 되지만 확장 가능합니까?), 가능한 태그의 고정 수를 추가합니다.항목에 대한 ID 열ID(잘못된 아이디어로 생각됨), 태그를 쉼표로 구분된 텍스트 열에 보관합니다(미쳤지만 작동할 수 있음).누군가가 스파스 매트릭스를 추천하는 것도 들었습니다만, 어떻게 하면 태그명이 우아하게 자랄 수 있을까요?
태그의 베스트 프랙티스가 누락되어 있습니까?
적절한 데이터베이스 상에서 실행 중인 외부 키가 있는 적절한 색인화된3개의 테이블(모든 항목을 저장하기 위한 테이블, 모든 태그 및 둘 사이의 관계용 테이블)이 적절하게 작동하고 적절하게 확장됩니다.
Table: Item
Columns: ItemID, Title, Content
Table: Tag
Columns: TagID, Title
Table: ItemTag
Columns: ItemID, TagID
보통은 Yaakov Ellis의 의견에 동의하지만, 이 특별한 경우에는 다른 실행 가능한 해결책이 있습니다.
2개의 테이블을 사용합니다.
Table: Item
Columns: ItemID, Title, Content
Indexes: ItemID
Table: Tag
Columns: ItemID, Title
Indexes: ItemId, Title
여기에는 다음과 같은 주요 이점이 있습니다.
첫 번째로, 3개의 테이블로 구성된 솔루션에서 다음과 같이 개발 작업을 훨씬 쉽게 개발할 수 있습니다.item검색해야 합니다.Tag테이블에서 엔트리가 이미 있는지 확인합니다.그리고 나서 당신은 그들과 함께 새로운 것을 해야 합니다.이것은 사소한 일이 아니다.
그러면 문의가 더 간단해집니다(아마도 더 빠를 수 있습니다).실행하는 주요 데이터베이스 쿼리는 세 가지가 있습니다.모두 출력Tags한 사람으로서ItemTag-Cloud를 그리고 하나의 태그 제목에 대한 모든 항목을 선택합니다.
하나의 항목에 대한 모든 태그:
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
하지만 몇 가지 단점도 있습니다.데이터베이스의 공간이 더 많이 소요될 수 있으며(디스크 작업이 더 느려지고 속도가 느려질 수 있음) 정규화되지 않아 불일치가 발생할 수 있습니다.
size 인수는 그다지 강력하지 않습니다.태그의 본질은 태그가 일반적으로 매우 작기 때문에 사이즈의 증가는 크지 않기 때문입니다.태그 제목에 대한 쿼리는 각 태그를 한 번만 포함하는 작은 테이블에서 훨씬 더 빠르다고 주장할 수 있습니다. 이것은 확실히 사실입니다.그러나 가입하지 않아도 되는 비용 절감과 그에 대한 좋은 지표를 구축할 수 있다는 사실을 고려하면 이를 쉽게 보상할 수 있습니다.물론 이것은 사용 중인 데이터베이스의 크기에 따라 크게 달라집니다.
모순된 주장도 약간 애매하다.태그는 자유 텍스트 필드이며 '모든 태그의 이름을 'foo'에서 'bar'로 변경'과 같은 예상된 작업은 없습니다.
따라서 tldr:나는 두 테이블로 된 해결책을 택할 것이다.(사실 난 할 거야.나는 이 기사에 대한 타당한 반론이 있는지 알아보려고 이 기사를 찾았다.)
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을 쉽게 조합하여 각 태그의 사용 빈도를 나타내는 태그 목록을 얻을 수 있기 때문입니다.
항목표:Itemid, taglist1, taglist2
이것은 빠르고 아이템 레벨에서 데이터를 쉽게 저장 및 검색할 수 있습니다.
병렬로 다른 테이블을 빌드합니다.태그 태그는 태그를 고유 식별자로 만들지 않으며, 두 번째 열에 공간이 부족하면 100개의 항목이 다른 행을 만듭니다.
이제 태그 아이템을 검색하는 동안 매우 빠릅니다.
언급URL : https://stackoverflow.com/questions/20856/recommended-sql-database-design-for-tags-or-tagging
'programing' 카테고리의 다른 글
| 데이터 바인딩을 통해 WPF 하이퍼링크의 텍스트를 설정하려면 어떻게 해야 합니까? (0) | 2023.04.14 |
|---|---|
| WPF 버튼을 링크처럼 보이게 하려면 어떻게 해야 하나요? (0) | 2023.04.14 |
| matplotlib에서 축 문자 회전 (0) | 2023.04.14 |
| 사전 키에서 빠르게 배열 (0) | 2023.04.09 |
| 다중 바인딩에서 1개의 바인딩에 대해 상수 값을 전달하려면 어떻게 해야 합니까? (0) | 2023.04.09 |