पदों के लिए पसंद या वोट


10

मैं एक छोटा सा कार्यक्रम बना रहा हूं जहां उपयोगकर्ता पोस्ट बनाते हैं या ब्लॉग लिखते हैं। उन पोस्टों पर, अन्य उपयोगकर्ता पोस्ट को फ़ेसबुक पर पसंद या नापसंद कर सकते हैं या पोस्ट को स्टाओवरफ़्लो के रूप में बढ़ा या घटा सकते हैं। मैं एक अच्छे डेटाबेस स्ट्रक्चर को जानना चाहूंगा जिसका आमतौर पर इस्तेमाल किया जाता है और प्रोग्राम उस स्ट्रक्चर के साथ कुशलता से काम करता है। मेरे पास दो विकल्प हैं

प्रथम

पद:

id   head   message   datepost   likes   dislikes
1     ab    anchdg     DATE      1,2,3   7,55,44,3

उपरोक्त तरीके से, idपोस्टिड है। पसंद के कॉलम में, 1,2,3उपयोगकर्ता की आईडी है जो पोस्ट या ब्लॉग को पसंद या अपग्रेड करता है। 7,55,44,3उन उपयोगकर्ताओं की आईडी है, जिन्होंने पोस्ट या ब्लॉग को नापसंद या अस्वीकृत किया है।

दूसरा

पद:

id    head  message   datepost
1     ab    anchdg     DATE

को यह पसंद है:

id    postid    userid
1       1         1
2       2         2

नापसंद:

id    postid    userid
1       1         7
2       1         55

इस तरह, मुझे पोस्ट की पसंद पाने के लिए पसंद और नापसंद के लिए दो अलग-अलग टेबल बनाने होंगे। इस तरह, टेबल यानी Likesऔर Dislikesभारी भरकम हो जाएंगे। इससे तालिका भारी और धीमी हो सकती है।

इसलिए, मैं जानना चाहूंगा कि इस कार्य को प्राप्त करने का बेहतर और मानक तरीका कौन सा है?


4
मैं मान रहा हूं कि कोई उपयोगकर्ता किसी पोस्ट को पसंद और नापसंद नहीं कर सकता है ? यदि ऐसा है, तो मेरे पास पसंद और नापसंद के लिए एक टेबल होगी, एक बीआईटी कॉलम के साथ (1 लाइक, नापसंद के लिए 0)।
dwjv

1
या आसान रकम के लिए 1 और -1
jkavalik

1
@dwjv पहले उदाहरण में, उपयोगकर्ता 3 ने वास्तव में, दोनों को पोस्ट पसंद और नापसंद किया है।
डेन हेंडरसन

जवाबों:


20

आपके द्वारा सामना की जाने वाली समस्या को डेटाबेस के "सामान्य रूप" के रूप में जाना जाता है, विशेष रूप से पहला सामान्य रूप। https://en.wikipedia.org/wiki/First_normal_form

समाप्‍त उपयोगकर्ता आईडी (प्रथम संस्‍करण) के साथ आपका डेटाबेस पहले सामान्‍य रूप में नहीं है।

आमतौर पर क्यों और कैसे सामान्यीकरण अच्छा माना जाता है, इसके लिए https://en.wikipedia.org/wiki/Database_normalization देखें ।

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

पुन: डेटाबेस भारी हो जाता है

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

दूसरी ओर, डेटाबेस को लाखों पंक्तियों को संभालने के लिए डिज़ाइन किया गया है। हमारे पास कई सौ मिलियन पंक्तियों के साथ डेटाबेस हैं, और गिनती () - संचालन तेज है। बहुत ज़्यादा तेज़। तो नहीं, यह एक प्रदर्शन अड़चन नहीं होगी।

अगला मुद्दा पठनीयता और स्थिरता का होगा।

उदाहरण के लिए, मुझे बताएं कि ये 2 कथन क्या करते हैं:

select count(*)
from posts
inner join likes on posts.postid = likes.postid
where postid = 7

select len(likes) - len(replace(likes, ',', ''))
from posts
where postid = 7

जैसा कि मैंने उल्लेख किया है, यदि करोड़ों या अरबों की पसंद तालिका में मौजूद है, तो क्या तालिका भारी नहीं होगी? क्या करोड़ों रिकॉर्ड वाली तालिका को खोजने में ज्यादा समय नहीं लगेगा क्योंकि तालिका बहुत तेजी से भरेगी?
हर्षित श्रीवास्तव

6
@ हर्षित श्रीवास्तव mysql सरल पंक्तियों की अरब पंक्तियों को संभाल सकते हैं, लेकिन कल्पना करें कि आपके उपयोगकर्ताओं की तालिका में स्ट्रिंग के रूप में उन बिल (डिस) को पसंद किया जाता है - जिनके साथ काम करना भी बड़ा और कठिन हो सकता है।
javavalik

3
एक बात @til_b सीधे उल्लेख नहीं करती है (लेकिन आम तौर पर सामान्य रूपों के उपयोग के माध्यम से निहित होती है) यह है कि दूसरा डिज़ाइन, ठीक से लागू किया गया है, अंतर्निहित डेटाबेस इंजन को संदर्भात्मक अखंडता बनाए रखने की अनुमति देगा जो पहले डिज़ाइन पैटर्न के साथ नहीं किया जा सकता है। अनिवार्य रूप से इसका मतलब है, यदि उपयोगकर्ता 4 हटा दिया जाता है, तो डेटाबेस लिंक किए गए डेटा को साफ़ कर देगा क्योंकि यह जानता है कि उपयोगकर्ता 4 रिकॉर्ड पर कौन से रिकॉर्ड निर्भर करते हैं। पहला डिज़ाइन इसके लिए अक्षम है क्योंकि डेटाबेस सहज ज्ञान युक्त नहीं जानता है कि स्ट्रिंग में संबंध कैसे प्रबंधित करें।
डेविड अंतरामियान

9

दूसरा तरीका ज्यादा बेहतर है क्योंकि आप एक पसंद / नापसंद को आसानी से जोड़ या हटा सकते हैं।

लेकिन आपको अपने दूसरे समाधान को जैसे या नापसंद के लिए एक तालिका का उपयोग करके संशोधित करना चाहिए।
लाइक / डिसलाइक टेबल के कॉलम आईडी, पोस्टिड, यूजरिड और अन्य जैसे एक या नापसंद के मूल्य के लिए होना चाहिए जैसे 1 नापसंद के लिए और 1 के लिए जैसे।

एक समग्र प्राथमिक कुंजी के रूप में post_id और user_id सेट करें और यह ठीक काम करता है।

समय के साथ तालिका का आकार बढ़ता जाएगा। लेकिन आपके पास केवल दो वास्तविक कॉलम हैं। आईडी और पसंद / नापसंद का मूल्य। पोस्टिड और यूजरिड केवल इससे जुड़े होते हैं और आपके उपयोगकर्ता और पोस्ट टेबल में संग्रहीत होते हैं।


3
आपके पास होना चाहिए user_id, post_idऔर valueतालिका में। अलग idकॉलम की जरूरत नहीं ।
javavalik

3
जैसा कि सुझाए गए प्रश्न पर @ jkavalik की टिप्पणी, 1 और -1 संभवतः 1 और 2 की तुलना में पसंद और नापसंद के लिए बेहतर मूल्य होंगे, क्योंकि यह एक साधारण तालिका योग के माध्यम से कुल स्कोर की गणना करने में सक्षम होगा, बजाय गिनती की गणना के "1" के साथ पंक्तियों की गिनती से "2" के साथ पंक्तियाँ।
डैन हेंडरसन

@ डैनहैडरसन: कुछ पसंद - नापसंद एक राशि से काफी तेज हो सकता है। (उस ने कहा, हालांकि, यह 1 और -1 के साथ भी काम करेगा।)
cHao

upvoted, यदि आप प्यार और क्रोध जैसे 2 और कार्यों को कहते हैं, तो आप यह कैसे करेंगे? मेरा मतलब पसंद के लिए 1 और 2 और कार्यों के साथ नापसंद के लिए -1
PirateApp

यदि आप sumकुछ भी नहीं करना चाहते हैं तो आप प्रेम = 2 और क्रोध = 3
जूलियन एस
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.