डेटाबेस में टिप्पणियाँ और पसंद को लागू करना


146

मैं एक सॉफ्टवेयर डेवलपर हूं। मुझे कोड से प्यार है, लेकिन मुझे डेटाबेस से नफरत है ... वर्तमान में, मैं एक वेबसाइट बना रहा हूं, जिस पर एक उपयोगकर्ता को पसंद के रूप में एक इकाई को चिह्नित करने की अनुमति दी जाएगी (जैसे एफबी में), इसे टैग करें और टिप्पणी करें

मैं इस कार्यक्षमता को संभालने के लिए डेटाबेस टेबल डिज़ाइन पर अटक जाता हूं। समाधान तुच्छ है, अगर हम ऐसा केवल एक ही प्रकार की चीज़ के लिए कर सकते हैं (जैसे। फोटो)। लेकिन मुझे इसे 5 अलग-अलग चीजों के लिए सक्षम करने की आवश्यकता है (अभी के लिए, लेकिन मैं यह भी मानता हूं कि यह संख्या बढ़ सकती है, क्योंकि पूरी सेवा बढ़ती है)।

मुझे यहां कुछ ऐसे ही सवाल मिले, लेकिन उनमें से किसी का भी संतोषजनक जवाब नहीं है, इसलिए मैं यह सवाल फिर से पूछ रहा हूं।

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

विस्तृत विवरण : मैं एक है तालिका User 3 और कुछ उपयोगकर्ता डेटा के साथ, और टेबल : Photoके साथ तस्वीरें , Articlesसाथ लेख , Placesसाथ स्थानों । मैं किसी भी लॉग इन उपयोगकर्ता को सक्षम करना चाहता हूं:

  • उन 3 तालिकाओं में से किसी पर टिप्पणी करें

  • पसंद के अनुसार उनमें से किसी को चिह्नित करें

  • उनमें से किसी को किसी टैग के साथ टैग करें

  • मैं हर तत्व के लिए पसंद की संख्या और उस विशेष टैग का उपयोग करने की संख्या को भी गिनना चाहता हूं।

1 सेंट दृष्टिकोण :

एक) के लिए टैग , मैं एक बनाएगा तालिका Tag [TagId, tagName, tagCounter] , तो मैं पैदा करेगा कई-से-अनेक रिश्तों तालिकाओं के लिए: Photo_has_tags, Place_has_tag, Article_has_tag

ख) टिप्पणियों के लिए एक ही मायने रखता है।

ग) मैं एक पैदा करेगा मेज LikedPhotos [idUser, idPhoto] , LikedArticles[idUser, idArticle], LikedPlace [idUser, idPlace]पसंद की संख्या को प्रश्नों द्वारा गणना की जाएगी (जो, मुझे लगता है कि खराब है)। तथा...

मैं वास्तव में पिछले भाग के लिए इस डिजाइन को पसंद नहीं करता, यह मेरे लिए बुरी तरह से बदबू आ रही है;)


2 एन डी दृष्टिकोण :

मैं एक तालिका ElementType [idType, TypeName == some table name]बनाऊंगा जिसे प्रशासक (मेरे) द्वारा उन तालिकाओं के नामों से आबाद किया जाएगा जिन्हें पसंद , टिप्पणी या टैग किया जा सकता है । फिर मैं टेबल बनाऊंगा :

a) LikedElement [idLike, idUser, idElementType, idLikedElement]और प्रत्येक के लिए उचित कॉलम के साथ टिप्पणियाँ और टैग के लिए समान। अब, जब मैं एक फ़ोटो बनाना चाहता हूँ, तो मैं सम्मिलित करूँगा:

typeId = SELECT id FROM ElementType WHERE TypeName == 'Photo'
INSERT (user id, typeId, photoId)

और स्थानों के लिए:

typeId = SELECT id FROM ElementType WHERE TypeName == 'Place'
INSERT (user id, typeId, placeId)

और इसी तरह ... मुझे लगता है कि दूसरा दृष्टिकोण बेहतर है, लेकिन मुझे ऐसा भी लगता है कि इस डिजाइन में भी कुछ गायब है ...

अंत में, मुझे यह भी आश्चर्य होता है कि तत्व को कितनी बार पसंद किया गया था इसके लिए काउंटर स्टोर करने के लिए सबसे अच्छी जगह है। मैं केवल दो तरीकों के बारे में सोच सकता हूं:

  1. तत्व में ( Photo/Article/Place) तालिका
  2. चुनिंदा गिनती () द्वारा।

मुझे उम्मीद है कि इस मुद्दे की मेरी व्याख्या अब अधिक गहन है।


क्या आपने XML पर विचार किया है?
कोडिब्यूस्टीन

1
मुझे शायद ही कभी इस तरह के सवाल मिलते हैं जो मेरे दिमाग में 100% हैं, आपका सवाल अजीब है! धन्यवाद @ कोको।
aderchox

जवाबों:


195

सबसे एक्स्टेंसिबल समाधान के लिए सिर्फ एक "आधार" तालिका ("पसंद", टैग और टिप्पणियों से जुड़ा) है, और इसमें से अन्य सभी तालिकाएं "विरासत" हैं। एक नई तरह की इकाई को जोड़ने में बस एक नई "विरासत में मिली" तालिका को जोड़ना शामिल है - यह स्वचालित रूप से संपूर्ण / टैग / टिप्पणी मशीनरी में प्लग करता है।

इसके लिए इकाई-संबंध शब्द "श्रेणी" है ( ईर्विन मेथड्स गाइड , अनुभाग: " सबटाइप रिलेशनशिप" देखें)। श्रेणी प्रतीक है:

वर्ग

मान लिया जाए कि उपयोगकर्ता कई संस्थाओं को पसंद कर सकता है, एक ही टैग को एक से अधिक इकाइयों के लिए उपयोग किया जा सकता है, लेकिन एक टिप्पणी इकाई-विशिष्ट है, आपका मॉडल इस तरह दिख सकता है:

ईआर डायग्राम


BTW, "ईआर श्रेणी" को लागू करने के लगभग 3 तरीके हैं:

  • एक तालिका में सभी प्रकार।
  • अलग-अलग तालिकाओं में सभी ठोस प्रकार।
  • अलग-अलग तालिकाओं में सभी ठोस और सार प्रकार।

जब तक आपके पास बहुत कठोर प्रदर्शन आवश्यकताएं नहीं होती हैं, तीसरा दृष्टिकोण संभवतः सबसे अच्छा होता है (जिसका अर्थ है कि भौतिक तालिका 1: 1 ऊपर दिए गए आरेख में स्थित हैं)।


2
महान जवाब, धन्यवाद। मुझे आशा है, मैं इसे कार्यान्वित करने का प्रबंधन करूंगा ... और मुझे आश्चर्य है कि Django ORM इसे मैप करने के लिए कैसे संभाल करेगा (या मैं खुद से ऐसा कैसे करूंगा ... लेकिन, वह दूसरी समस्या है;)) लेकिन, क्या आप समझा सकते हैं? मेरे कारण, मुझे लगता है कि मुझे यह ठीक से समझ में नहीं आ रहा है - आपने मेरे लिए क्या तैयार किया है (धन्यवाद!) आपके द्वारा उल्लिखित तीसरा तरीका है?
कोकोस

2
@ कोको अनिवार्य रूप से, दृष्टिकोण (3) का अर्थ है कि ईएनटीटीआई एक तालिका है, फोटो एक तालिका है, आर्टिकल एक टेबल है और प्लेट एक टेबल है। दृष्टिकोण (2) का मतलब होगा कि ईएनटीटीआई के लिए कोई तालिका नहीं है और दृष्टिकोण (1) का मतलब होगा कि केवल एक तालिका है। इन सभी दृष्टिकोणों का अस्तित्व (उनकी ताकत और कमजोरियों के साथ) इस तथ्य का दुर्भाग्यपूर्ण परिणाम है कि एक सामान्य RDBMS मूल रूप से तालिका विरासत का समर्थन नहीं करता है।
ब्रानको दिमित्रिजेविक

1
+1 महान स्पष्टीकरण और "श्रेणियों" पर संदर्भ के लिए धन्यवाद। मैं इसके करीब एक प्रश्न पोस्ट करने जा रहा था, लेकिन आपने इसका जवाब यहां दिया।
andy holaday

2
@BrankoDimitrijevic इकाई तालिकाओं क्यों नहीं कर सकता फोटो, लेख, प्लेस का अपना PK है जैसे PhotoID, ArticleID आदि लेकिन एक FK के रूप में Entity_ID के लिए एक और कॉलम भी है? क्या यह अनावश्यक है?
वॉल्यूम एक

3
@ ओरियन 9223372036854775807 के लिए अधिकतम BIGINTहै। मान लें कि आप प्रत्येक पंक्ति में एक पंक्ति सम्मिलित करते हैं, तो आप ~ 300 बिलियन वर्षों में उपलब्ध मूल्यों से बाहर निकल जाएंगे। निश्चित रूप से, आप तब तक 128-बिट पूर्णांकों को पोर्ट कर पाएंगे!
ब्रांको दिमित्रिजेविक

22

चूंकि आप डेटाबेस से "नफरत" करते हैं, आप एक को लागू करने की कोशिश क्यों कर रहे हैं? इसके बजाय, किसी ऐसे व्यक्ति से मदद करें जो इस सामान को प्यार करता है और साँस लेता है।

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

यदि यह एक वन प्रोजेक्ट है, तो संग्रहीत प्रक्रियाओं का उपयोग करके डेटाबेस इंटरफ़ेस को सरल ऑपरेशन में प्रोग्राम करें: add_user, update_user, add_comment, add_like, upload_photo, list_comments, आदि। कोड की एक पंक्ति में भी स्कीमा को एम्बेड न करें। इस तरीके से, डेटाबेस स्कीमा को किसी भी कोड को प्रभावित किए बिना बदला जा सकता है: केवल संग्रहीत प्रक्रियाओं को स्कीमा के बारे में पता होना चाहिए।

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


2
क्योंकि मुझे इसे खुद से लागू करने की जरूरत है। कम से कम अभी के लिए ... और, मुझे लगा कि शायद यह एक अच्छा अवसर है कि डेटाबेस को थोड़ा सा पसंद करना शुरू किया जाए;) संग्रहीत प्रक्रिया के साथ आपके सुझाव के बारे में धन्यवाद। किसी को पता है, अगर वे Django ORM द्वारा स्वचालित रूप से मैप किए जाते हैं?
कोकोस

6
मुझे आपके अंतिम वाक्य से प्यार है - यह हमेशा दूसरी बार बेहतर होता है।
लुईस

2
यह हमेशा दूसरी बार बेहतर होता है। युप
गामर

20

यह एक सामान्य विचार है कि स्टाइल के क्षेत्र के नाम पर ज्यादा ध्यान न दें, लेकिन संबंध और संरचना के लिए अधिक

यहां छवि विवरण दर्ज करें

इस छद्मकोड को ID 5 के साथ फ़ोटो की सभी टिप्पणियाँ मिलेंगी।
* क्रियाओं से,
जहां क्रियाएँ .id_Stuff = 5
और क्रियाएँ. typeStuff = "फ़ोटो"
और क्रियाएँ. typeAction = "टिप्पणी"

इस छद्मकोड को सभी पसंद या उपयोगकर्ता मिलेंगे, जिन्हें आईडी 5 के साथ फोटो पसंद आया
(आप केवल पसंद की राशि प्राप्त करने के लिए गिनती () का उपयोग कर सकते हैं)

SELECT * FROM actions  
WHERE actions.id_Stuff = 5  
AND actions.typeStuff="photo"  
AND actions.typeAction = "like"  

मुझे लगता है कि आप टिप्पणियों में भी पसंद कर सकते हैं, जैसे, एक टिप्पणी में "जैसे" लिंक पर क्लिक करना। इस क्वेरी को ID 133:SELECT * FROM actions WHERE actions.id=133 AND actions.typeStuff = "comment" AND actions.typeAction = "like"
user964260

1
मैं निश्चित रूप से अपने सिस्टम की आगे की रिलीज़ के लिए इस समाधान को याद रखूंगा :)
कोकोस

मेरे पास 2 सामान तालिकाएं हैं stuff1 और stuff2 ... मैंने इस आरेख का अनुसरण किया है लेकिन इस का उपयोग करते समय sql त्रुटि है ... stuff1, stuff2 दो स्वतंत्र तालिकाओं के साथ उनकी स्वतंत्र प्राथमिक कुंजियाँ हैं, और कार्रवाई तालिका में एक स्तंभ id_stuff है जो कि संदर्भित है इन दो टैब सामान 1, सामान 2। अब उदाहरण के लिए stuff1 में 5 पंक्तियाँ हैं, stuff2 में 10 पंक्तियाँ हैं, जब मैं id_stuff के साथ एक्शन टेबल में पंक्ति जोड़ने की कोशिश करता हूँ, तो 5 से कम कुछ भी '3' कहता है कि यह क्वेरी को कार्यान्वित करता है क्योंकि id1stuff '3' के साथ दोनों पंक्ति 1 में मौजूद है और सामान 2, लेकिन अगर मैं 5 से अधिक id_stuff के साथ पंक्ति जोड़ने की कोशिश करता हूं ... (अगली टिप्पणी जारी रखें)
vikas devde

1
यदि किसी को इस तरह से लागू करना है, तो यह नए उपयोगकर्ता के उपयोगकर्ता को अधिक कठिन बना देता है। इसके लिए एक और तालिका की आवश्यकता होगी।
ग्रेग एल

4
id_stuffकॉलम में प्रत्येक तीन तालिकाओं में अद्वितीय मान कैसे होंगे ?
वॉल्यूम एक

0

जहां तक ​​मैं समझता हूं। कई तालिकाओं की आवश्यकता है। उनके बीच कई संबंध हैं।

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

यदि आप अपने डेटाबेस आरेख पोस्ट करते हैं। मैं संबंध बना सकता हूं।
erencan

0

जिस पैटर्न की आपको आवश्यकता है, उसे देखें। क्या उनमें से कोई भी विशेष रूप से कठिन या मेरी एक डिजाइन पसंद या अयोग्य बनाने के लिए लगता है?

यदि कम तालिकाओं की आवश्यकता होती है, तो इसके पक्ष में नहीं

इस मामले में:

  1. टिप्पणी जोड़ें: आप या तो एक विशेष रूप से कई / कई टेबल चुनते हैं या एक सामान्य तालिका में एक विशिष्ट विशिष्ट पहचानकर्ता के साथ सम्मिलित करते हैं जो पसंद किया जा रहा है, मुझे लगता है कि क्लाइंट कोड आपके दूसरे मामले में थोड़ा सरल होगा।
  2. आइटम के लिए टिप्पणियां ढूंढें: यहां ऐसा लगता है कि एक सामान्य तालिका का उपयोग करना थोड़ा आसान है - हमारे पास केवल एक ही क्वेरी है जिसे इकाई के प्रकार द्वारा पैरामीटर किया गया है
  3. किसी व्यक्ति द्वारा किसी एक चीज़ के बारे में टिप्पणियां प्राप्त करना: किसी भी मामले में सरल क्वेरी
  4. सभी चीजों के बारे में किसी व्यक्ति द्वारा सभी टिप्पणियां खोजें: यह थोड़ा सा या तो तरीका लगता है।

मुझे लगता है कि आपके "भेदभावपूर्ण" दृष्टिकोण, विकल्प 2, कुछ मामलों में सरल प्रश्नों को जन्म देता है और दूसरों में बहुत बुरा नहीं लगता है इसलिए मैं इसके साथ जाऊंगा।


0

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


-1

टिप्पणियों और आदि के लिए प्रति इकाई तालिका का उपयोग करने पर विचार करें - अधिक तालिकाएं - बेहतर शार्किंग और स्केलिंग। मुझे पता है कि सभी रूपरेखाओं के लिए कई समान तालिकाओं को नियंत्रित करना कोई समस्या नहीं है।

एक दिन आपको ऐसी संरचना से रीड्स को अनुकूलित करने की आवश्यकता होगी। आप आसानी से आधार के ऊपर एग्रेगेटिंग टेबल बना सकते हैं और लिखने पर थोड़ा खो सकते हैं।

शब्दकोश के साथ एक बड़ी तालिका एक दिन बेकाबू हो सकती है।


अधिक तालिकाओं का मतलब है कि यह कम रखरखाव योग्य होगा। व्यक्तिगत तालिकाएँ अधिकांश d / bs द्वारा शार्प की जा सकती हैं।
21
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.