2008-12-29 17 views
10

कहें कि मेरे पास डेटाबेस तालिका में प्रत्येक पंक्ति में एक समाचार आलेख के बारे में जानकारी है। तालिका में एक पूर्णांक "सॉर्ट" कॉलम होता है ताकि ऑर्डर को निर्देशित किया जा सके जिसमें लेख वेब साइट पर प्रस्तुत किए जाएं। मैं इस तरह के क्रम को सबसे अच्छा कैसे कार्यान्वित और बनाए रख सकता हूं।डेटाबेस तालिका पंक्तियों के क्रम क्रम को बनाए रखना

जिस समस्या से मैं बचाना चाहता हूं, वह है कि लेख 1,2,3,4, .., 100 और जब आलेख संख्या 50 अचानक दिलचस्प हो जाता है तो इसे क्रमबद्ध संख्या 1 पर सेट हो जाती है और फिर उनके बीच सभी लेख उनके क्रम संख्या में वृद्धि होनी चाहिए।

निश्चित रूप से, प्रारंभिक क्रम संख्या 100,200,300,400 आदि को सेट करने के लिए कुछ जगह छोड़ने के लिए छोड़ देता है लेकिन कुछ बिंदु पर यह टूट जाएगा।

क्या ऐसा करने का कोई सही तरीका है, शायद एक पूरी तरह से अलग दृष्टिकोण?


जोड़ा -1:

सभी लेख के शीर्षक सामग्री को जोड़ने एक सूची में दिखाया जाता है, तो हाँ सभी क्रमित किए गए आइटम शो में एक बार कर रहे हैं।

जोड़ा -2:

एक आइटम जरूरी सूची के शीर्ष पर नहीं ले जाया जाता है; किसी भी आइटम को आदेशित सूची में कहीं भी रखा जा सकता है।

+0

एक बार में 100 से बढ़ोतरी आपको रीडरिंग के लिए बहुत अधिक छूट देगी, और आप लंबे समय तक संख्याओं से बाहर नहीं होंगे (भले ही वे 16-बिट हस्ताक्षरित संख्याएं हों - 32-बिट वाले अकेले रहने दें) । और यदि आप अंतराल कम हो रहे हैं तो आप समय-समय पर किराए पर कर सकते हैं। –

उत्तर

8

यदि मैं आपकी समस्या को सही ढंग से समझता हूं; मैं कुछ प्रकार के रैंकिंग इंडेक्स नंबर वाले कॉलम का उपयोग करूंगा। यह संख्या अद्वितीय नहीं है। रैंक की गणना करने के लिए आपको कुछ प्रकार के एल्गोरिदम के साथ आने की आवश्यकता होगी।

फिर रैंकिंग कॉल को संभालने के लिए एक माध्यमिक कॉलम के साथ रैंकिंग कॉलम पर क्रमबद्ध करें (शायद निर्माण तिथि या कुछ)।

+1

या ऑर्डर संशोधन दिनांक-समय, ताकि आप उन्हें पुन: व्यवस्थित कर सकें। –

0

अवरोही क्रम क्रम का उपयोग करें, यानी उच्चतम क्रम संख्या शीर्ष पर दिखाई जाती है।

यदि कोई पुराना लेख सूची के शीर्ष पर रखा जाना चाहिए, तो बस अपना सॉर्ट कॉलम MAX (सॉर्ट करें) +1 पर सेट करें। पूरी मेज को फिर से भरने की जरूरत नहीं है।

अद्यतन अपनी टिप्पणी के बाद: चल बिन्दु को

बदलें सॉर्ट क्रम। यदि किसी लेख के सॉर्ट ऑर्डर को दो अन्य लेखों के बीच पुनर्व्यवस्थित किया जाता है, तो नया सॉर्ट मान ((पिछले लेख का क्रमबद्ध करें) + (अगले लेख का क्रमबद्ध करें))/2. अन्यथा, सेट करें MAX + 1 पर सॉर्ट करें।

-1

सभी लेख शीर्षक सामग्री से लिंक करने वाली सूची में दिखाए जाते हैं, इसलिए हाँ सभी सॉर्ट किए गए आइटम एक साथ दिखाए जाते हैं।

+0

यह प्रश्न में है। कृपया इसे हटा दें। –

-1

किसी आइटम को सूची के शीर्ष पर स्थानांतरित नहीं किया जाता है, किसी आइटम को आदेशित सूची में कहीं भी रखा जा सकता है।

+0

हे लोक्स, आप इन टिप्पणियों को या तो उचित उत्तर टिप्पणी अनुभाग में क्यों नहीं जोड़ते हैं, या अपना मूल प्रश्न संपादित नहीं करते हैं? (ईमानदारी का इरादा) –

+0

क्षमा करें। टिप्पणी होनी चाहिए थी। –

+0

अब जब मैंने इसे प्रश्न पर ले जाया है, तो कृपया इसे हटाएं। –

0
समस्या मैं से बचने के लिए रहा है लेख गिने 1,2,3,4, .. चाहते

, 100

मैं तुम्हें कोशिश नहीं और होने अपने तरह महत्वपूर्ण हो सुझाव है आपकी प्राथमिक कुंजी, या अद्वितीय हो। यदि वे कुंजी अद्वितीय नहीं हैं तो आपके पास एक ही मूल्य के साथ कई आइटम हो सकते हैं। आप शायद अपनी सॉर्ट कुंजी को एक साधारण 1-10 स्केल बनाना चाहते हैं।

तो शायद स्तर 10 पर चीजें बेहद दिलचस्प होंगी, 5 सामान्य होगी, और 1 बेहद उबाऊ होगा। जब कुछ उबाऊ या अधिक रोचक हो जाता है, तो बस अपनी सॉर्ट कुंजी के मान को ऊपर या ऊपर समायोजित करें।

9

सही भूल जाएं - जिस समस्या को आप मुझसे बचाना चाहते हैं, वह एक बड़ा सौदा नहीं है, बल्कि, आपके आरडीबीएमएस के आधार पर केवल कुछ अपडेट स्टेटमेंट्स (मैं ओरेकल मान रहा हूं और आप लेख को ऊपर ले जा रहे हैं " सूची):

UPDATE Articles 
SET sort_number = sort_number + 1 
WHERE sort_number BETWEEN :new_sort_number and :current_sort_number - 1; 

UPDATE Articles 
SET sort_number = :new_sort_number 
WHERE article_id = :article_id; 

सबसे बड़ी चेतावनी यह है कि एसईटी कार्यक्षमता सभी आरडीबीएमएस में समान नहीं होती है।

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

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

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

0

ऐसा करने के लिए, हमने पंक्तियों को पूर्णांक बढ़ाने के लिए सेट किया है, फिर वस्तुओं को स्थानांतरित करने के लिए संग्रहीत प्रो का उपयोग करें। Proc में दो तर्क, आइटम की वर्तमान अनुक्रमणिका, और नई अनुक्रमणिका जो आप इसे ले जाना चाहते हैं। यह एक अद्यतन आइटम इंडेक्स = इंडेक्स + साइन सेट करता है (@newidx - @oldidx) जहां आइटममैक्स (@newidx, @oldidx) और itemMin (@newidx, @oldidx) के बीच इंडेक्स के बीच में आइटम अपडेट करने के लिए और फिर एक अद्यतन जो अद्यतन करता है नई सूचकांक के लिए वास्तविक वस्तु। यह स्मृति से सिर्फ वास्तविक कोड नहीं है। हमारी तालिका में, हमारे पास दो कॉलम, आईडी और इंडेक्स हैं ताकि एक बिंदु पर आप एक ही इंडेक्स पर दो आइटमों के साथ समाप्त हो जाएं, हम उन्हें आईडी द्वारा अलग कर सकते हैं। इसे आइटम पर अपडेट करके -1 के सूचकांक में अद्यतन करके, फिर बाकी को अपडेट करके और अंत में नई वस्तु को नए सूचकांक में ले जाकर घुमाया जा सकता है।

0

मैं उत्तर के साथ जाऊंगा ज्यादातर लोग कह रहे हैं, अर्थात् आपके रिकॉर्ड में सॉर्ट/ब्याज मूल्य के साथ आपकी तालिका में एक अलग कॉलम होना चाहिए। यदि आप अभी भी मजबूत रहते हुए किसी प्रकार के तर्क तर्क में कारक बनाना चाहते हैं, तो आप किसी दिए गए समयावधि के लिए डेटा "दृश्य" को आजमा सकते हैं और शामिल कर सकते हैं।

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

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

5

लिंक की गई सूची डेटा संरचना के बाद अपनी तालिका का मॉडल करें। "सॉर्ट" कॉलम से छुटकारा पाएं, इसके बजाय अगला_article_id कॉलम है जो इसके बाद के अगले लेख को इंगित करता है। फिर जब आप स्थिति 50 पर एक नया आलेख जोड़ना चाहते हैं तो आपको अपने नए आलेख को इंगित करने के लिए केवल आलेख # 49 को अपडेट करना होगा, फिर अपने नए आलेख को एक लेख # 49 पर इंगित करें।

+6

कृपया मुझे एक SELECT क्वेरी दें जिसका उपयोग मैं सभी लेख प्राप्त करने के लिए कर सकता हूं, सही ढंग से क्रमबद्ध –

1

वास्तविक संख्या का उपयोग करना सबसे कम्प्यूटेशनल रूप से कुशल विकल्प प्रतीत होता है। आप दो पंक्तियों के बीच आधा दूरी जोड़ कर दो अन्य लोगों के बीच एक पंक्ति को स्थानांतरित कर सकते हैं। पंक्ति 1 और पंक्ति 2 के बीच एक नया स्थानांतरित करने के लिए, newrow = row1 + (row2 - row1) /2.0 के रूप में newrow की गणना करें। हालांकि, फ्लोटिंग पॉइंट सीमाओं के कारण, यह श्रृंखला (डबल परिशुद्धता का उपयोग करके) 53 पुनरावृत्तियों में अभिसरण होगी। इतना बुरा मामला आप केवल 53 आवेषण कर सकते हैं (अधिक यदि आप हमेशा अंतिम नई और पंक्ति 2 के बीच सम्मिलित नहीं होते हैं)। यह अंतराल को छोड़ने और उन्हें भरने के विचार के समान है। अद्यतन करने का विचार कम कुशल है, लेकिन कुछ निश्चित आवेषण के बाद नहीं टूटता है। अनुक्रमित कॉलम को रखने से शायद मदद मिलेगी।

+0

प्रत्येक नई पंक्ति के रैंक में केवल 100 जोड़ना आसान नहीं होगा और फिर नई "बीच में" पंक्तियों को फिट करना आसान होगा उन 100 स्लॉट में से एक। यह अभी भी अभिसरण है लेकिन यह कम जटिल है। – cdmckay

3

(अंग्रेजी के लिए खेद है। मैं पढ़ रहा हूं)

बहुत आसान है। आप "प्रमुखता छेद"

संरचना आप 2 स्तंभ

1) पी = 32 बिट पूर्णांक

2) आदेश = 64 बिट bigint (BIGINT, डबल नहीं है की जरूरत है की जरूरत है !!!)

1) जब आप पहले नए रिकॉर्ड डालते हैं तो आपको ऑर्डर = राउंड (max_bigint/2) सेट करना होगा।

2) यदि आप तालिका आप सेट करना होगा की शुरुआत में सम्मिलित = दौर ("पहले रिकॉर्ड के आदेश"/2)

3) यदि आप तालिका के अंत में सम्मिलित आप सेट करना होगा = दौर ("max_bigint - पिछले रिकॉर्ड के आदेश"/2)

4) यदि आप बीच में डालने आप = क्रम सेट करना होगा दौर ("से पहले रिकॉर्ड के आदेश - के बाद रिकॉर्ड के आदेश"/2)

इस विधि बहुत बड़ी कार्डिटिलिटी है। यदि आपके पास बाधा त्रुटि है या यदि आपको लगता है कि आपके पास छोटी कार्डिनालिटी है तो आप ऑर्डर कॉलम (सामान्यीकृत) का पुनर्निर्माण कर सकते हैं।

सामान्यीकरण (इस संरचना के साथ) के साथ अधिकतमता स्थिति में आप 32 बिट में "कार्डिनालिटी होल" प्राप्त कर सकते हैं।

बहुत आसान और तेज़ है!

कोई दोगुना याद नहीं है !!! केवल आईएनटी - ऑर्डर सटीक मूल्य है!

0

अलकिनी के उत्तर पर निर्माण करने के लिए (मैं सीधे इसका जवाब दूंगा लेकिन मुझे इस पल के लिए अंक/विशेषाधिकारों की कमी है)। यह विधि तभी काम करती है जब नया प्रदर्शन ऑर्डर नया से कम हो। यदि यह दूसरी तरफ है तो आपको लेखों को दूसरी दिशा में बीच में स्थानांतरित करने की आवश्यकता है।

अगर (new_sort_number == current_sort_number)

Do nothing 

अगर (new_sort_number < current_sort_number)

UPDATE Articles 
SET sort_number = sort_number + 1 
WHERE sort_number BETWEEN :new_sort_number and :current_sort_number - 1; 

अगर (new_sort_number> current_sort_number)

UPDATE Articles 
SET sort_number = sort_number - 1 
WHERE sort_number BETWEEN :current_sort_number + 1 and :new_sort_number; 
तो या तो मामले में

, अद्यतन लेख जो चले गए।

UPDATE Articles 
SET sort_number = :new_sort_number 
WHERE article_id = :article_id; 

आशा है कि किसी अन्य व्यक्ति को सामान्यीकृत ऑर्डर ऑर्डर अपडेट एल्गोरिदम की तलाश करने में मदद मिलेगी।

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