2011-10-04 15 views
8

मैं अपने वीएलई के लिए एक इनाम प्रणाली विकसित कर रहा हूं जो क्लाइंट-साइड/डिस्प्ले प्रोसेसिंग के लिए जावास्क्रिप्ट के लिए जावास्क्रिप्ट और डेटाबेस के लिए MySQL के साथ तीन अलग-अलग तकनीकों का उपयोग करता है।डेटाबेस संरचना को अनुकूलित करना

मैंने अपनी "लेनदेन" तालिका के तीन स्क्रीनशॉट संलग्न किए हैं। इसकी संरचना, कुछ उदाहरण रिकॉर्ड और इसके विवरण का एक सिंहावलोकन।

आधार यह है कि कर्मचारियों के पुरस्कार अच्छे छात्रों के लिए छात्रों को इंगित करते हैं। इसका मतलब यह हो सकता है कि 30 छात्रों के वर्गों को एक ही समय में अंक दिए जाते हैं। कर्मचारियों की 300 अंक/सप्ताह की सीमा है और वर्तमान में लगभग 85 कर्मचारी सिस्टम तक पहुंच रहे हैं (यह बढ़ सकता है)।

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

यह जल्दी काम करना प्रतीत होता था, लेकिन तीन सप्ताह के भीतर मेरे पास पहले से ही डेटाबेस में 12,000 से अधिक लेनदेन हैं।

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

var Points = { "Recipient_ID" : "0", "Points" : "0" }; 

function getPoints (data) { 
    for (var i = 0; i < data.length; i++) { 
     if (Points[data[i].Recipient_ID]) { 
      Points[data[i].Recipient_ID] = parseInt(Points[data[i].Recipient_ID]) + parseInt(data[i].Points); 
     } else { 
      Points[data[i].Recipient_ID] = data[i].Points; 
     } 
    } 
} 

जब प्रणाली आंतरिक रूप में लॉग इन करने, इस काम करने के लिए प्रकट होता है: एक ही रास्ता मैं वर्तमान में अपने सिस्टम पर ऐसा कर सकते निम्नलिखित जे एस एक "SELECT * FROM 'transactions'" करते हैं और का उपयोग कर एक सरणी में सभी जानकारी डाल करने के लिए है जल्दी से पर्याप्त हालांकि, बाहरी रूप से लॉग इन करते समय, इस प्रक्रिया में लगभग 20 सेकंड लगते हैं, और इस प्रकार छात्रों के अंक मान प्रदर्शित नहीं करते हैं जब तक आप कुछ बार क्लिक/खोज नहीं करते हैं।

मैं इन लेनदेन का उपयोग करने के लिए अपने PHP में निम्नलिखित कोड का उपयोग कर रहा:

function getTotalPoints() { 
    $sql = "SELECT * 
     FROM `transactions`"; 

    $res = mysql_query($sql); 
    $rows = array(); 
    while($r = mysql_fetch_assoc($res)) { 
     $rows[] = $r; 
    } 

    if ($rows) { 
     return $rows; 
    } else { 
     $err = Array("err_id" => 1); 
     return $err; 
    } 
} 

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

उदाहरण रिकॉर्ड Example records

तालिका संरचना Table structure

टेबल सिंहावलोकन Table overview

असाइन अंक इंटरफ़ेस Assign Points interface

अग्रिम में बहुत धन्यवाद।

+0

अच्छी तरह से पूछा ... – slandau

उत्तर

3

आपकी समस्या आपकी क्वेरी है:

SELECT * FROM `transactions` 

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

SELECT SUM(points) FROM `transactions` WHERE Recipient_ID=[x] 

या यदि आप अपने सभी छात्रों के लिए सभी राशियों हैं:

SELECT Recipient_ID, SUM(points) AS Total_Points FROM `transactions` GROUP BY Recipient_ID; 

एक विशेष क्षेत्र पर चयन में तेजी लाने के लिए आप उस क्षेत्र के लिए एक सूचकांक जोड़ सकते हैं। यह चयन को तेज करेगा, खासतौर से तालिका बढ़ने के साथ ही।

ALTER TABLE `transactions` ADD INDEX Recipient_ID (Recipient_ID); 

या आप transactions में सभी प्रविष्टियों का एक पृष्ठवार सूची प्रदर्शित करना चाहते हैं:

SELECT * FROM `transactions` LIMIT [page*num_records_per_page],[num_records_per_page]; 

e.g.: SELECT * FROM `transactions` LIMIT 0,25 ORDER BY Datetime; # First 25 records 
+0

धन्यवाद बहुत टॉम। इसने मेरे सिस्टम पर कई क्षेत्रों में गति में सुधार किया है। – dunc

1

तो आप विशेष रूप से किसी भी बिंदु पर या कम से 1 व्यक्ति के लिए खोज सकते मैं सूचकांक Recipient_ID चाहते कम से कम अपने डेटा को अधिक प्रभावी ढंग से ग्रुप करने में सक्षम हो। यदि आप category_id द्वारा समूह का चयन करते हैं तो मैं श्रेणी_आईडी में एक अलग या संयुक्त सूचकांक भी जोड़ूंगा।

दूसरा सुझाव ग्रुप और फ्लाई पर अपने डेटा को बढ़ाना होगा। उदाहरण के लिए:

SELECT Recipient_ID, Category_ID, SUM(points) FROM transactions GROUP BY Recipient_ID, Category_ID 

इन दो सुझाव नाटकीय रूप से, क्योंकि PHP/जे एस ओर अपने छात्रों के लिए कुल अंकों की गणना करने के बजाय अपने प्रदर्शन नवीनीकृत करना चाहिए, तो आप सीधे डेटाबेस पर करेंगे।

2

टॉम के सुझाव में जोड़कर, आप अपने डेटाबेस को और सामान्यीकृत करने पर विचार करना चाहेंगे। मुझे लगता है कि तुम अब 3 टेबल है:

students (id, name, ...)

staff (id, name, ...)

transactions (id, student_id, staff_id, points, date, reason)

एक और अधिक सामान्यीकृत प्रपत्र कम डेटा के साथ अधिक तालिकाओं का उपयोग करता है:

students (id, name, ...)

staff (id, name, ...)

transactions (id, staff_id, points, date, reason)

transactions_students (transaction_id, student_id)

तो एक सौदे जोड़ना एक दो चरण की प्रक्रिया हो जाता है: सबसे पहले आप एक लेन-देन रिकॉर्ड बनाने, और फिर आप transactions_students में कई रिकॉर्ड डालें, हर एक को एक छात्र के लिए लेन-देन को जोड़ने। ध्यान दें कि आप एक राय यह है कि वास्तव में चयन के लिए मूल denormalized मेज की तरह बर्ताव बना सकते हैं, कुछ की तरह:

CREATE VIEW vw_transactions AS SELECT transactions.*, transactions_students.student_id FROM transactions INNER JOIN transactions_students WHERE transactions_students.transaction_id = transactions.id 

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

+0

धन्यवाद tdammers। क्या आप कृपया मुझे एक उदाहरण दे सकते हैं कि आप उन तालिकाओं में लेनदेन कैसे स्टोर करेंगे? मेरे पास वास्तव में छात्र या स्टाफ टेबल नहीं हैं, क्योंकि सभी आईडी हमारे VLE से 'Frog.API.get (' users.getInfo ')' कॉल का उपयोग करके आती हैं। – dunc

+1

मेरा जवाब संपादित किया गया। HTH। – tdammers

संबंधित मुद्दे