टैग या टैगिंग के लिए अनुशंसित SQL डेटाबेस डिज़ाइन [बंद]


288

मैंने टैगिंग को लागू करने के कुछ तरीकों के बारे में सुना है; TagID और ItemID के बीच मानचित्रण तालिका का उपयोग करना (मुझे समझ में आता है, लेकिन क्या यह स्केल है?), ItemID में संभावित TagID कॉलम की निश्चित संख्या जोड़कर (एक बुरे विचार की तरह लगता है), एक टेक्स्ट कॉलम में टैग रखते हुए जो कॉमा को अलग कर दिया गया है (लगता है) पागल लेकिन काम कर सकता है)। मैंने भी सुना है कि किसी ने एक विरल मैट्रिक्स की सिफारिश की है, लेकिन फिर टैग नाम कैसे सुंदर रूप से बढ़ते हैं?

क्या मुझे टैग के लिए एक सर्वोत्तम अभ्यास याद आ रहा है?


9
ठीक है यह प्रश्न # 20856 है, (लगभग) यही प्रश्न # 48475 है, इस प्रश्न के पूछे जाने के कम से कम दो सप्ताह बाद।
dlamblin

9
एक और दिलचस्प सवाल यह है कि "एसओ कैसे टैग लगाता है?"
मुस्तफा

1
एक और दिलचस्प सवाल यह है कि "क्या आप उनका अंतर्राष्ट्रीयकरण करेंगे, और यदि ऐसा है, तो कैसे?"
डैनमैन

1
दिलचस्प तुलना (विशिष्ट पोस्ट करता है): databaseoup.com/2015/01/tag-all-things.html
a_horse_with_no_name

जवाबों:


406

तीन तालिकाओं (सभी वस्तुओं के भंडारण के लिए एक, सभी टैग के लिए एक, और दोनों के बीच के संबंध के लिए एक), उचित रूप से अनुक्रमित, एक उचित डेटाबेस पर चलने वाली विदेशी कुंजियों के साथ, अच्छी तरह से और बड़े पैमाने पर काम करना चाहिए।

Table: Item
Columns: ItemID, Title, Content

Table: Tag
Columns: TagID, Title

Table: ItemTag
Columns: ItemID, TagID

32
इसे "टोक्सी" समाधान के रूप में जाना जाता है, आप इसके बारे में अतिरिक्त जानकारी यहां पा सकते हैं: howto.philippkeller.com/2005/04/24/Tags-Database-schemas
Pixel Developer

16
एक चीज़ जो यहाँ नहीं दिखाई गई है वह है हिराचल "टैग" या टैग तालिका में श्रेणियां। यह आमतौर पर उन साइटों पर आवश्यक होता है जिनमें श्रेणियां और उपश्रेणियाँ होती हैं, लेकिन टैगिंग के लचीलेपन की आवश्यकता होती है। उदाहरण के लिए, रेसिपी साइट्स, ऑटो पार्ट्स साइट्स, बिज़नेस डाइरेक्टरीज़ इत्यादि इस प्रकार के डेटा आमतौर पर केवल एक ही श्रेणी में फिट नहीं होते हैं, इसलिए इसका जवाब देना टैगिंग है लेकिन आपको नेस्टेड सेट मॉडल या निकटता सूची मॉडल जैसी किसी चीज़ का उपयोग करने की आवश्यकता है अपनी टैग तालिका में।
एचके १

5
मैं एचके 1 के साथ सहमत हूं यह संरचना + तालिका के साथ संभव है: टैगग्रुप कॉलम: टैगग्रोपूआईड, शीर्षक तालिका: टैग कॉलम: टैग, शीर्षक, टैगग्रुपआईड
थंडर

जब मैं टेबल में सीएसएस कॉलम जोड़ना चाहता हूं, तो मैं टैग टेबल में सीएसएस कॉलम जोड़ दूंगा?
अमिताभ ११'१५ को

10
@ftvs: लिंक फिर से टूटा, नया लिंक है howto.philippkeller.com/2005/04/24/Tags-Database-schemas
hansaplast

83

आम तौर पर मैं याकोव एलिस से सहमत होता हूं लेकिन इस विशेष मामले में एक और व्यवहार्य समाधान है:

दो तालिकाओं का उपयोग करें:

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

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

इसके कुछ प्रमुख फायदे हैं:

पहले यह विकास को बहुत सरल बनाता है: डालने और 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

लेकिन कुछ कमियां भी हैं: यह डेटाबेस में अधिक जगह ले सकता है (जो अधिक डिस्क संचालन को धीमा कर सकता है) और यह सामान्यीकृत नहीं है जिससे असंगतता हो सकती है।

आकार का तर्क इतना मजबूत नहीं है क्योंकि टैग की बहुत प्रकृति यह है कि वे आम तौर पर बहुत छोटे होते हैं इसलिए आकार में वृद्धि एक बड़ी नहीं है। कोई यह तर्क दे सकता है कि टैग शीर्षक के लिए क्वेरी एक छोटी तालिका में बहुत तेज है जिसमें प्रत्येक टैग केवल एक बार होता है और यह निश्चित रूप से सच है। लेकिन इसमें शामिल नहीं होने के लिए बचत को ध्यान में रखते हुए और इस तथ्य पर कि आप उन पर एक अच्छा सूचकांक बना सकते हैं, इसके लिए आसानी से क्षतिपूर्ति कर सकते हैं। यह निश्चित रूप से आपके द्वारा उपयोग किए जा रहे डेटाबेस के आकार पर बहुत अधिक निर्भर करता है।

असंगतता की दलील थोड़ी मूट भी है। टैग स्वतंत्र पाठ क्षेत्र हैं और 'बार "के लिए सभी टैग" फू "का नाम बदलने जैसा कोई अपेक्षित संचालन नहीं है।

तो tldr: मैं दो-टेबल समाधान के लिए जाऊंगा। (वास्तव में मैं जा रहा हूं। मुझे यह लेख देखने के लिए मिला कि क्या इसके खिलाफ वैध तर्क हैं।)


क्या "Index: ItemId, Title" का मतलब प्रत्येक इंडेक्स या दोनों के लिए एक इंडेक्स है?
डैनमैन

आम तौर पर दो सूचकांक। यद्यपि आप जिस डेटाबेस का उपयोग कर रहे हैं, उस पर निर्भर हो सकता है।
१०:५० पर स्कीथिनोड

1
टैग तालिका में ItemId और Tag एक संयुक्त कुंजी है? या आपके पास एक पीके भी है?
रिप्पो

2
इस तरह से आप "अप्रयुक्त" टैग नहीं बना सकते हैं इसलिए एक आइटम पर "टैग जोड़ें" सुविधा का प्रदर्शन किया जाना चाहिए। अन्य विधि पर, "टैग जोड़ें" सुविधा को स्वतंत्र रूप से किया जा सकता है
गियानलुका गेथिनी

1
@Quilang। मेरा अब भी मानना ​​है कि यह इस बात पर निर्भर करता है कि आप क्या कर रहे हैं :) मैंने इसे विभिन्न परियोजनाओं में दोनों तरह से लागू किया। अपने अंतिम एक में मैं एक 3 टेबल समाधान के साथ समाप्त हुआ क्योंकि मुझे "टैग-प्रकार" (या टैग पर कुछ अन्य मेटा जानकारी) की आवश्यकता थी और टैग के एक करीबी चचेरे भाई से कुछ कोड का पुन: उपयोग कर सकता था: पैरामीटर। लेकिन उसी परियोजना में मैंने इस विधि का उपयोग एक करीब के चचेरे भाई के लिए भी किया: झंडे (जैसे। 'बेचा हुआ', 'नया', 'गर्म')
Scheintod

38

यदि आप एक डेटाबेस का उपयोग कर रहे हैं जो मैप-कम का समर्थन करता है, जैसे कि काउचडब, एक सादे पाठ क्षेत्र या सूची फ़ील्ड में टैग संग्रहीत करना वास्तव में सबसे अच्छा तरीका है। उदाहरण:

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

समूह के साथ इसे चलाना = सही परिणाम टैग नाम से समूह देगा, और यहां तक ​​कि टैग का सामना करने की संख्या की एक संख्या भी लौटाएगा। यह पाठ में किसी शब्द की घटनाओं को गिनने के समान है ।


4
+1 कुछ NoSQL कार्यान्वयन भी देखकर अच्छा लगा।
Xeoncross

@NickRetallack लिंक काम नहीं कर रहा है। यदि आप कर सकते हैं, तो कृपया इस उत्तर को अपडेट करें।
xralf

ठीक है, मैंने लिंक को
आर्काइव.ओआरजी के

13

टैग संग्रहीत करने के लिए एकल स्वरूपित टेक्स्ट कॉलम [1] का उपयोग करें और इसे अनुक्रमित करने के लिए एक सक्षम पूर्ण पाठ खोज इंजन का उपयोग करें। बूलियन प्रश्नों को लागू करने का प्रयास करते समय आप समस्याओं को कम कर देंगे।

यदि आपको अपने पास मौजूद टैग के बारे में विवरण की आवश्यकता है, तो आप या तो इसे गुप्त रूप से बनाए रखी गई तालिका में रख सकते हैं या जानकारी निकालने के लिए बैच जॉब चला सकते हैं।

[१] कुछ RDBMS यहां तक ​​कि एक मूल सरणी प्रकार भी प्रदान करते हैं जो कि एक पार्सिंग चरण की आवश्यकता नहीं होने से भंडारण के लिए बेहतर अनुकूल हो सकते हैं, लेकिन पूर्ण पाठ खोज के साथ समस्या पैदा कर सकते हैं।


क्या आप किसी पूर्ण-पाठ खोज इंजन से अवगत हैं जो किसी शब्द पर भिन्नता नहीं खोजता है? उदाहरण के लिए, पुस्तक रिटर्न पुस्तकों की खोज? इसके अलावा, आप "c ++" जैसे टैग के बारे में क्या करते हैं? उदाहरण के लिए, SQL सर्वर इंडेक्स में प्लस साइन्स को स्ट्रिप करेगा। धन्यवाद।
जोनाथन वुड

स्फिंक्स - sphinxsearch.com
रोमन

यह 3-भाग ट्यूटोरियल शायद उन लोगों के लिए उपयोगी है जो इस मार्ग (पूर्ण पाठ खोज) पर जा रहे हैं। : यह PostgreSQL देशी सुविधाओं का उपयोग कर रहा है shisaa.jp/postset/postgresql-full-text-search-part-1.html
विल

क्या यह प्रदर्शन के मामले में चयनित उत्तर से बेहतर है?

कैसे के बारे में varchar 255 का उपयोग करते हुए, अल्पविराम टैग अलग है और उस पर kfull पाठ सूचकांक जोड़ रहा है?

9

मैंने हमेशा टैग को एक अलग तालिका में रखा है और फिर एक मानचित्रण तालिका बनाई है। बेशक, मैंने कभी भी बड़े पैमाने पर कुछ भी नहीं किया है।

एक "टैग" टेबल और एक मैप टेबल होने से टैग क्लाउड्स उत्पन्न करने के लिए यह बहुत तुच्छ हो जाता है और जैसे कि आप आसानी से SQL के साथ टैग की एक सूची प्राप्त करने के लिए एक साथ रख सकते हैं कि कितनी बार प्रत्येक टैग का उपयोग किया जाता है।


6
यह और भी आसान है अगर आप मैपिंग टेबल का उपयोग नहीं करते हैं :)
Scheintod

0

मैं निम्नलिखित डिजाइन का सुझाव देता हूं: आइटम तालिका: आइटम, टैगलिस्ट 1, टैगलिस्ट 2
यह तेजी से होगा और आइटम स्तर पर डेटा को बचाने और पुनर्प्राप्त करने में आसान होगा।

समांतर बिल्ड में एक अन्य तालिका: टैग टैग टैग अद्वितीय पहचानकर्ता नहीं बनाते हैं और यदि आप 2 कॉलम में अंतरिक्ष से बाहर निकलते हैं, जिसमें 100 आइटम दूसरी पंक्ति बनाने की सुविधा देते हैं।

अब टैग के लिए आइटम खोजते समय यह सुपर फास्ट होगा।


en.wikipedia.org/wiki/First_normal_form हालांकि इसके अपवाद हैं, आप इसे असामान्य कर सकते हैं, लेकिन यहां नहीं
धीरज
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.