परिचय
PostgreSQL डेवलपर्स को बड़े बाइनरी डेटा के लिए दो संभावित स्टोरेज सुविधाओं के बीच चयन करने का मौका देता है:बाइटा और लार्जऑब्जेक्ट्स।
बड़ी वस्तुएं लंबे समय से आसपास हैं, और PostgreSQL के पास बड़े बाइनरी डेटा को संग्रहीत करने का एक स्मार्ट तरीका है। यह इसे LOBLKSIZE (BLCKSZ के आगे) के टुकड़ों में विभाजित करके करता है। इस तरह pg_largeobject से टुपल्स टोस्ट टेबल पर नहीं फैलेंगे।
दूसरी ओर बाइटा बाइनरी डेटा को सीधे टुपल में संग्रहीत करता है, जिससे आपकी स्कीमा कैसी दिखती है, इसके आधार पर खराब प्रदर्शन हो सकता है।
यह बहुत अच्छा लगता है यदि आपके पास इन बाइनरी फ़ाइलों के हेरफेर से निपटने के लिए एक बुद्धिमान इंटरफ़ेस है, विशेष रूप से यदि अद्यतन पूरी बाइनरी फ़ाइल के केवल एक छोटे से हिस्से को संशोधित करता है।
लेकिन आम तौर पर हम उस कोड को लिखने की जहमत नहीं उठाते जो इसका फायदा उठाता है, और इसके बजाय हम पूरे बाइनरी डेटा को फिर से लिखते हैं।
उन चीजों में से एक जो मुझे विश्वास है कि लोग बड़ी वस्तुओं को अपनाते हैं, डेटाबेस सर्वर से सीधे फाइल सिस्टम में फ़ाइलों को आयात और निर्यात करने के लिए उपलब्ध कार्य हैं। इसमें एक खामी है:यदि एप्लिकेशन किसी भिन्न सर्वर पर है, तो आपको फ़ाइल को उस स्थान पर ले जाने के लिए अधिक कोड की आवश्यकता होगी जहां इसकी आवश्यकता है।
एक समस्या जिसका आप सामना कर सकते हैं
पिछले दिनों मुझे जावा सीएएस सिस्टम से उपयोगकर्ता सत्रों की जानकारी संग्रहीत करने के लिए उपयोग किए जाने वाले डेटाबेस की जांच करनी थी। मैंने पाया कि डेटाबेस में लगभग 100 मिलियन बड़ी वस्तुएं थीं, बहुत बड़ी नहीं।
मैं उपयोगकर्ता तालिकाओं पर गया और उन फ़ील्ड की जाँच की जिनमें oid . था फ़ील्ड, और फिर मैं pg_largeobject_metadata के साथ उन फ़ील्ड के मानों को क्रॉस-रेफ़रेंस कर रहा हूं टेबल। मैंने पाया कि उन बड़ी वस्तुओं में से 96% जहां अनाथ हैं। वे बड़ी वस्तुएं हैं जिन्हें उपयोगकर्ता तालिकाओं से किसी भी टपल द्वारा संदर्भित नहीं किया गया था।
आगे की जांच ने निष्कर्ष निकाला कि हाइबरनेट ने ओआईडी फ़ील्ड के साथ टुपल्स को हटाते या अपडेट करते समय बनाई गई बड़ी वस्तुओं को शुद्ध करने का ख्याल नहीं रखा। तो यह बड़ी मात्रा में ब्लोट उत्पन्न कर रहा था जिसे वैक्यूम करके साफ नहीं किया जा सकता था, लेकिन मैन्युअल रूप से pg_largeobjects तालिका से शुद्ध किया जाना था।
CAS डेटाबेस के विशेष मामले में, यह क्वेरी अभी भी उपयोग में आने वाली बड़ी वस्तुओं की पहचान करने के लिए कार्य करती है:
SELECT unnest(array[expiration_policy, authentication, services_granted_access_to]) FROM public.ticketgrantingticket UNION SELECT unnest(array[expiration_policy, service]) FROM public.serviceticket
क्वेरी का उपयोग बड़ी वस्तुओं की सूची से बाहर करने के लिए किया जा सकता है जिन्हें हटाना है। कुछ इस तरह:
SELECT lo_unlink(pg_largeobject_metadata.oid) FROM pg_largeobject_metadata WHERE pg_largeobject_metadata.oid NOT IN ( SELECT unnest(array[expiration_policy, authentication, services_granted_access_to]) FROM public.ticketgrantingticket UNION SELECT unnest(array[expiration_policy, service]) FROM public.serviceticket )
निष्कर्ष
अन्य प्रकार के डेटा की तरह ही बड़ी वस्तुओं के अपने मुद्दे होते हैं (विशेषकर बड़े बाइनरी डेटा को स्टोर करने के लिए प्रकारों का उपयोग करते समय)। पेशेवरों का लाभ उठाना और विपक्ष को कम करना डेवलपर्स और डेटाबेस प्रशासकों पर निर्भर है।
हमने क्लीन-अप करने के लिए एक संभावित क्वेरी दी, लेकिन एक अच्छा एक्सटेंशन भी है जो ट्रिगर के साथ अनाथ बड़ी वस्तुओं को साफ करता है:बड़े ऑब्जेक्ट मैनेजर
कुछ लोग प्रत्येक अद्यतन . पर एक ट्रिगर निष्पादित करने के बजाय शांत घंटों के दौरान एक शुद्ध क्वेरी चलाना पसंद कर सकते हैं और हटाएं . बहुत, बहुत कम वाले सिस्टम पर अद्यतन करें और/या हटाएं दर, प्रत्येक तालिका पर एक ट्रिगर जिसमें oid . होता है फ़ील्ड, एक और अधिक सुरुचिपूर्ण समाधान प्रतीत होता है। और ट्रिगर फ़ंक्शन को निष्पादित करने के लिए कोई भी प्रदर्शन हानि अनावश्यक होगी।
किसी भी मामले में, बड़ी वस्तुओं में अभी भी महान प्रशंसक हैं, सबसे अधिक संभावना है कि बाइनरी डेटा को सीधे स्थानीय फाइल सिस्टम में आयात और निर्यात करने के लिए प्रदान किए गए आंतरिक कार्यों के कारण। बाइटिया के साथ आप आमतौर पर एप्लिकेशन टियर पर अधिक मेमोरी का उपयोग करते हैं। बाइनरी फ़ील्ड को पूरी तरह से एक वेरिएबल में पढ़ना और फिर इसे प्रोसेस करना एक बहुत ही सामान्य प्रक्रिया है।
मैं बाइटा का उपयोग करने के बारे में कुछ लिख सकता हूं जिसका उपयोग मैंने अपने पिछले विकास में भविष्य के ब्लॉग पोस्ट में किया था।