database - क्या पृष्ठांकन योजनाएं तेजी से बदलती हुई सामग्री सूची को संभाल सकती हैं?




pagination complex-event-processing (3)

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

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

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

पृष्ठ पर अंक लगाना कठिन है जब आपकी सामग्री रैंकिंग जल्दी बदल सकती है, और यहां तक ​​कि जब उन रैंकिंग में प्रति-उपयोगकर्ता भिन्न हो (चलिए अनंत स्क्रॉल को एक प्रकार की पृष्ठांकन के रूप में देखते हैं, जहां लिंक अदृश्य हो सकते हैं।) दो कठिन समस्याएं हैं: शीर्ष पर नई गयी सामग्री, और पुनः सामग्री पुनः

चलो नव-जुड़ी हुई सामग्री के बारे में भूल जाते हैं, और स्वीकार करते हैं कि आपको इसे देखने के लिए पेज 1 रीफ्रेश करना होगा। चलो भी ढोंग करते हैं हम शुद्ध ORDER BY position कर रहे हैं; यदि आप कुछ और के द्वारा आदेश दे रहे हैं, तो आपको विंडो फ़ंक्शन का उपयोग करना पड़ सकता है हमारे पृष्ठों में प्रति पृष्ठ पशुओं की 4 पंक्तियाँ हैं वे शुरू करते हैं:

+----+----------+-----------+
| id | position^|  animal   |
+----+----------+-----------+
|  1 |        1 | Alpacas   |
|  2 |        2 | Bats      |
|  3 |        3 | Cows      |
|  4 |        4 | Dogs      |
|  5 |        5 | Elephants |
|  6 |        6 | Foxes     |
|  7 |        7 | Giraffes  |
|  8 |        8 | Horses    |
+----+----------+-----------+

पृष्ठ 1 प्राप्त करने के बाद, और पृष्ठ 2 लाने से पहले, बहुत सी मदें घूमती हैं डीबी अब है:

+----+----------+-----------+
| id | position^|  animal   |
+----+----------+-----------+
|  4 |        1 | Dogs      |
|  2 |        2 | Bats      |
|  1 |        3 | Alpacas   |
|  5 |        4 | Elephants |
|  6 |        5 | Foxes     |
|  7 |        6 | Giraffes  |
|  3 |        7 | Cows      |
|  8 |        8 | Horses    |
+----+----------+-----------+

तीन सामान्य दृष्टिकोण हैं:

ऑफसेट / सीमा दृष्टिकोण

यह विशिष्ट अनुभवहीन दृष्टिकोण है; रेल में, यह कैसे होगा I_paginate और Kaminari काम करते हैं अगर मैं पृष्ठ 2 लाने चाहता हूं, तो मैं करूँगा

SELECT * FROM animals
ORDER BY animals.position
OFFSET ((:page_num - 1) * :page_size) 
LIMIT :page_size;

जो 5-8 पंक्तियों को प्राप्त करता है मैं हाथियों को कभी नहीं देखूँगा, और मैं गायों को दो बार देखूंगा

अंतिम बार देखा गया आईडी दृष्टिकोण

Reddit एक अलग दृष्टिकोण लेता है पृष्ठ आकार के आधार पर पहली पंक्ति की गणना के बजाय, क्लाइंट आपके द्वारा देखी गई आखिरी मद की आईडी को ट्रैक करता है, जैसे कोई बुकमार्क। जब आप "अगले" को दबाते हैं, तो वे उस बुकमार्क से आगे बढ़ना शुरू करते हैं:

SELECT * FROM animals
WHERE position > (
  SELECT position FROM animals 
  WHERE id = :last_seen_id
) 
ORDER BY position
LIMIT :page_size;

कुछ मामलों में, यह पृष्ठ / ऑफसेट से बेहतर काम करता है लेकिन हमारे मामले में, कुत्तों, आखिरी बार देखा गया पोस्ट, # 1 के लिए ज़ूम किया गया तो ग्राहक ग्राहक को भेजता है ?last_seen_id=4 , और मेरे पृष्ठ 2 में बैट, अल्पाकास, हाथी और लोमड़ी है ?last_seen_id=4 मैंने किसी जानवर को नहीं छोड़ा, लेकिन मैंने बैट और अल्पाकास को दो बार देखा

सर्वर साइड स्टेट

हैकर्स न्यूज (और हमारी साइट, अभी) सर्वर-साइड रिलीज़ेशन के साथ यह हल करती है; वे आपके लिए पूरे परिणाम सेट (या कम से कम कई पेज अग्रिम में?) स्टोर करते हैं, और "अधिक" जब मैं पृष्ठ 2 लेता हूं, तो मैं "मेरी मूल क्वेरी का पृष्ठ 2" पूछता हूं। यह एक ही ऑफसेट / सीमा गणना का उपयोग करता है, लेकिन चूंकि यह मूल प्रश्न के खिलाफ है, मुझे बस परवाह नहीं है कि चीजें अब चारों ओर घूमती हैं मैं हाथियों, लोमड़ियों, जिराफ, और घोड़े देखता हूं। कोई dups, कोई चूक आइटम नहीं

नकारात्मक पक्ष यह है कि हमें सर्वर पर कई राज्यों को स्टोर करना होगा एचएन पर, जो रैम में संग्रहीत होता है, और वास्तविकता में उन निरंतरताएं अक्सर समाप्त हो जाती हैं, इससे पहले कि आप "अधिक" बटन दबा सकें, आपको वैध लिंक ढूंढने के लिए पृष्ठ 1 पर वापस जाने के लिए मजबूर होना पड़ता है। अधिकांश अनुप्रयोगों में, आप इसे मेम्कैच में या डेटाबेस में ही (अपने खुद के टेबल का उपयोग कर, या ओरेकल या पोस्टग्रेश एसक्यूएल में, होल्डलेबल कर्सर का उपयोग करके) में संग्रहीत कर सकते हैं। आपके आवेदन के आधार पर, एक प्रदर्शन हिट हो सकता है; PostgreSQL में, कम से कम, आपको सही डाटाबेस कनेक्शन को फिर से मारने का एक तरीका मिलना होगा, जिसके लिए बहुत चिपचिपा राज्य या कुछ चालाक बैक-एंड रूटिंग की आवश्यकता होती है।

क्या ये केवल तीन संभावित दृष्टिकोण हैं? यदि नहीं, तो क्या इस बारे में पढ़ने के लिए मुझे Google रस देने वाला कंप्यूटर-साइंस अवधारणा है? क्या पूरे परिणाम सेट को संचित किए बिना निरंतरता के दृष्टिकोण का अनुमान लगाने के तरीके हैं? दीर्घकालिक, जटिल घटना-स्ट्रीमिंग / बिंदु-इन-टाइम सिस्टम है, जहां "परिणाम 1 पिक्चर प्राप्त किए जाने वाले पल के रूप में सेट" हमेशा के लिए व्युत्पन्न होता है। उस की कमी ...?


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

लेकिन मुझे लगता है कि चौथी संभावना है, जो तराजू से बहुत अच्छी तरह से, जब तक:

  1. आपको कोई डुप्लिकेट की गारंटी नहीं है, केवल एक उच्च संभावना है
  2. जब तक आप डुप्लिकेट से बचते हैं तब तक स्क्रॉल के दौरान कुछ सामग्री अनुपलब्ध होने के साथ ठीक हो

समाधान "आखिरी बार देखा गया आईडी" समाधान का एक प्रकार है: ग्राहक को एक नहीं रहना चाहिए, लेकिन 5 या 10 या 20 बुकमार्क - कुछ बहुत ही पर्याप्त है कि आप उन्हें कुशलतापूर्वक स्टोर कर सकते हैं। क्वेरी की तरह दिखने समाप्त होता है:

SELECT * FROM posts
WHERE id > :bookmark_1
AND id > :bookmark_2
...
ORDER BY id

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

यदि भविष्य में छेद या बेहतर उत्तर हैं, तो मैं इस उत्तर को खुशी से स्वीकार नहीं करूंगा।


पार्टी के लिए बहुत देर हो चुकी है लेकिन यहां कुछ ऐसा है जो हमने प्रयोग किया था। हम निरंतर लोडिंग का उपयोग कर रहे हैं, न कि उन पृष्ठों पर जो उपयोगकर्ता आगे बढ़कर आगे बढ़ेगा

क्लाइंट उन सभी आईडी की एक सूची बनाता है जो इसे प्रदर्शित किया गया है, इसलिए पहले सेट के बाद यह हो सकता है: 4,7,19,2,1,72,3

जब हम अधिक सामग्री लोड करते हैं, हम उसी प्रकार से एक ही क्वेरी करते हैं लेकिन इसे इस पर जोड़ें: WHERE id (4,7,19,2,1,72,3)

नहीं में सूची में तेजी से बढ़ सकता है हमारे लिए यह कोई मुद्दा नहीं है क्योंकि हमारे आंतरिक उपकरण में आमतौर पर कई नतीजे नहीं होते हैं।

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





complex-event-processing