PostgreSQL में भंडारण छवियाँ


111

ठीक है, इसलिए मैं एक ऐसे एप्लिकेशन पर काम कर रहा हूं, जो C # .NET में लिखे फ्रंट एंड के साथ विंडोज बॉक्स में इमेजेस सर्व करने के लिए एक लिनक्स बैक-एंड रनिंग पोस्टग्रेसीक्यूएल का उपयोग करेगा, हालांकि फ्रंट-एंड में शायद ही बात हो। मेरा सवाल यह है कि:

  • Postgres में भंडारण छवियों से निपटने का सबसे अच्छा तरीका क्या है?

चित्र लगभग 4-6 मेगापिक्सल के हैं, और हम 3000 से ऊपर की तरफ जमा कर रहे हैं। यह भी ध्यान रखना अच्छा हो सकता है: यह एक वेब एप्लिकेशन नहीं है, एक साथ डेटाबेस को एक्सेस करने में लगभग दो फ्रंट-एंड होंगे।

जवाबों:


64

2012 में अद्यतन, जब हम उस छवि के आकार, और छवियों की संख्या देखते हैं, बढ़ रहे हैं और बढ़ रहे हैं, सभी अनुप्रयोगों में ...

हमें "मूल छवि" और "संसाधित छवि" के बीच कुछ अंतर की आवश्यकता है, जैसे थंबनेल।

जैसा कि जेकोबी का जवाब कहता है, दो विकल्प हैं, फिर, मैं सलाह देता हूं:

  • बूँद का उपयोग करें (बाइनरी लार्ज ओबजेक्ट): मूल छवि की दुकान के लिए, अपनी मेज पर। इवान का जवाब देखें (ब्लूज़ बैक करने में कोई समस्या नहीं है!), पोस्टग्रेक्यूएल अतिरिक्त आपूर्ति मॉड्यूल , हाउ-टूएस आदि।

  • DBlink के साथ एक अलग डेटाबेस का उपयोग करें : मूल छवि की दुकान के लिए, दूसरे (एकीकृत / विशेष) डेटाबेस पर। इस मामले में, मैं बाइटा पसंद करता हूं , लेकिन बूँद उसी के पास है। डेटाबेस को अलग करना एक "एकीकृत छवि webservice" के लिए सबसे अच्छा तरीका है।

  • bytea (BYTE Array) का उपयोग करें : कैशिंग थंबनेल छवियों के लिए। वेब-ब्राउज़र पर तेज़ी से भेजने के लिए (रेंडरिंग की समस्या से बचने के लिए) और सर्वर प्रोसेसिंग को कम करने के लिए छोटी छवियों को कैश करें। कैश भी आवश्यक मेटाडेटा, जैसे चौड़ाई और ऊंचाई। डेटाबेस कैशिंग सबसे आसान तरीका है, लेकिन अपनी आवश्यकताओं और सर्वर कॉन्फ़िगरेशन (उदा। अपाचे मॉड्यूल) की जांच करें: फ़ाइल सिस्टम पर स्टोर थंबनेल बेहतर हो सकते हैं, प्रदर्शन की तुलना करें। याद रखें कि यह एक (एकीकृत) वेब-सेवा है, फिर एक अलग डेटाबेस (कई बैकअप के साथ) में संग्रहीत किया जा सकता है, कई तालिकाओं की सेवा कर सकता है। PostgreSQL बाइनरी डेटा प्रकार मैनुअल , बाइटा कॉलम के साथ परीक्षण आदि भी देखें ।

NOTE1: आज "दोहरे समाधान" (डेटाबेस + फाइल सिस्टम) का उपयोग पदावनत (!) है। दोहरे के बजाय "केवल डेटाबेस" का उपयोग करने के कई फायदे हैं। PostgreSQL में निर्यात / आयात / इनपुट / आउटपुट के लिए तुलनीय प्रदर्शन और अच्छे उपकरण हैं।

टिप्पणी 2: याद PostgreSQL केवल है bytea , एक डिफ़ॉल्ट Oracle की जरूरत नहीं ब्लॉब : "SQL मानक परिभाषित करता है (...) ब्लॉब इनपुट प्रारूप bytea से अलग है, लेकिन उपलब्ध कराई गई कार्यों और ऑपरेटरों ज्यादातर एक ही हैं।", मैनुअल


EDIT 2014 : मैंने आज के ऊपर मूल पाठ नहीं बदला है (मेरा जवाब अप्रैल 22 '12, अब 14 वोटों के साथ), मैं आपके परिवर्तनों के लिए उत्तर खोल रहा हूं (देखें "विकी मोड", आप संपादित कर सकते हैं!), प्रूफरीडिंग के लिए। और अपडेट के लिए
प्रश्न स्थिर है (@ इवांस के '08 जवाब 19 वोटों के साथ), कृपया, इस पाठ को बेहतर बनाने में मदद करें।


2
"... दोहरे समाधान" (डेटाबेस + फाइल सिस्टम) के उपयोग के लिए संदर्भ क्या है ... "?
फेल

2019 की कुछ खबरें! चूंकि 2018 पोस्टग्रेस्ट वेब को बाइटा के सीधे आउटपुट का समर्थन करता है । इसका उपयोग करने के लिए यह एनजीआईएनएक्स सरल विन्यास देखें । बाइनरी आउटपुट पर पोस्टग्रेस्ट गाइड
पीटर क्रूस

52

रे जकोबी का जवाब:

बाइटिया एक "सामान्य" कॉलम होने का अर्थ है कि जब आप इसे लाते हैं तो मूल्य पूरी तरह से मेमोरी में पढ़ा जा रहा है। ब्लब्स, इसके विपरीत, आप स्टडआउट में स्ट्रीम कर सकते हैं। जो सर्वर मेमोरी फुटप्रिंट को कम करने में मदद करता है। विशेष रूप से, जब आप 4-6 MPix छवियों को संग्रहीत करते हैं।

ब्लड बैक करने में कोई समस्या नहीं। pg_dump बड़ी वस्तुओं को बैकअप में शामिल करने के लिए "-b" विकल्प प्रदान करता है।

इसलिए, मैं pg_lo_ * का उपयोग करना पसंद करता हूं, आप अनुमान लगा सकते हैं।

Re Kris Erickson का जवाब:

मैं इसके विपरीत कहूंगा :)। जब छवियां केवल आपके द्वारा संग्रहीत डेटा नहीं होती हैं, तो उन्हें फ़ाइल सिस्टम पर संग्रहीत न करें जब तक कि आपके पास बिल्कुल न हो। अपने डेटा संगति के बारे में हमेशा सुनिश्चित होना और "एक टुकड़े में" (डीबी) डेटा को प्राप्त करना ऐसा लाभ है। BTW, PostgreSQL संरक्षण स्थिरता में महान है।

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


14
10 साल बाद, क्या आपको लगता है कि आपके अंक अभी भी मान्य हैं? तब से कोई अपडेट?
लेवेंटुन्वर

3
@leventunver नहीं, पकड़ नहीं करने के लिए अंक। उदाहरण के लिए पहले BYTEA"सामान्य" कॉलम होने के बारे में। पोस्टग्रेज ने कई वर्षों से / से कॉलम के लिए स्ट्रीमिंग का समर्थन किया है BYTEA, जिसका अर्थ है कि आपको मेमोरी में सामग्री को स्टोर करने से पहले उसे डीबी में स्टोर करने की आवश्यकता नहीं है।
ऑलिगॉफ्रेन

29

डेटाबेस में, दो विकल्प हैं:

  • bytea। एक कॉलम में डेटा संग्रहीत करता है, बैकअप के हिस्से के रूप में निर्यात किया जाता है। सहेजने और पुनः प्राप्त करने के लिए मानक डेटाबेस फ़ंक्शंस का उपयोग करता है। अपनी आवश्यकताओं के लिए अनुशंसित।
  • धब्बे। डेटा को बाहरी रूप से संग्रहीत करता है, आमतौर पर बैकअप के हिस्से के रूप में निर्यात नहीं किया जाता है। सहेजने और पुनः प्राप्त करने के लिए विशेष डेटाबेस फ़ंक्शंस की आवश्यकता होती है।

मैं हजारों पंक्तियों के साथ छवियों के 10 + gb पिछले संग्रह में बड़ी सफलता के साथ बाइटा कॉलम का उपयोग किया है। पीजी की टोस्ट कार्यक्षमता बहुत अधिक किसी भी लाभ की उपेक्षा करती है जो खिलती है। फ़ाइल नाम, सामग्री-प्रकार, आयाम आदि के लिए आपको मेटाडेटा कॉलम को किसी भी स्थिति में शामिल करना होगा।


1
10GB ज्यादा नहीं है :-( मैं
टीबी के

2
@ValentinHeinitz टीबी के लिए, वेनिला छोटे पाठ कॉलम के साथ भी संघर्ष को रोकता है।
sudo

23

2015 के मध्य तक त्वरित अपडेट:

फ़ाइलों को अधिक उपयुक्त डेटाबेस में संग्रहीत करने के लिए, आप Postgres विदेशी डेटा इंटरफ़ेस का उपयोग कर सकते हैं । उदाहरण के लिए फ़ाइलों को एक GridFS में रखें जो MongoDB का हिस्सा है। फिर इसे पोस्टग्रेज में एक्सेस करने के लिए https://github.com/EnterpriseDB/mongo_fdw का उपयोग करें

इसके फायदे हैं, कि आप इसे Postrgres और MongoDB में उपयोग / पढ़ / लिख / बैकअप कर सकते हैं, जो आपको और अधिक लचीलेपन पर निर्भर करता है।

फ़ाइल सिस्टम के लिए विदेशी डेटा रैपर भी हैं: https://wiki.postgresql.org/wiki/Foreign_data_wrappers#File_Wrappers

एक उदाहरण के रूप में आप इसे उपयोग कर सकते हैं: https://multicorn.readthedocs.org/en/latest/foreign-data-wrappers/fsfdw.html (संक्षिप्त उपयोग उदाहरण के लिए यहां देखें)

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


1
धन्यवाद .. क्या विदेशी डेटा रैपर (file_fdw) छवियों के लिए लेखन पहुंच प्रदान करते हैं? मैं Postgresql में एक FileSystem और उसके मेटाडेटा में छवियों को संग्रहीत करना चाहता हूं, लेकिन मुझे निरंतरता भी बनाए रखना है। क्या आपके पास इसका विस्तृत समाधान है? क्या कोई अन्य एक्सटेंशन उपलब्ध है? Multicorn अजगर की जरूरत है और मैं अजगर का उपयोग किए बिना क्या करने वाले पसंद करेंगे ..
जे Khatwani

1
हां उनके पास पहुंच है। वे दोनों दिशाओं में / से पूरी तरह से सुसंगत हैं। और नहीं, मैं एक समान समाधान के बारे में नहीं जानता जो अजगर के बिना ऐसा करता है।
केनाकोर्न केटसॉम्बट

18

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

मूल

डेटाबेस में छवियों को तब तक स्टोर न करें जब तक कि आपके पास बिल्कुल न हो। मैं समझता हूं कि यह एक वेब एप्लिकेशन नहीं है, लेकिन अगर कोई साझा फ़ाइल स्थान नहीं है, तो आप डेटाबेस में फ़ाइल के स्थान को बचाने के लिए इंगित कर सकते हैं।

//linuxserver/images/imagexxx.jpg

तब शायद आप जल्दी से एक वेबसर्वर सेट कर सकते हैं और डेटाबेस में (साथ ही स्थानीय पथ) वेब यूआरएल को स्टोर कर सकते हैं। जबकि डेटाबेस एलओबी और 3000 छवियों (4-6 मेगापिक्सेल, 500K एक छवि ग्रहण कर सकते हैं) को संभाल सकते हैं। 1.5 गिग्स बहुत अधिक स्थान नहीं है फ़ाइल सिस्टम एक डेटाबेस की तुलना में बड़ी फ़ाइलों को संग्रहीत करने के लिए बहुत बेहतर डिज़ाइन किए गए हैं।


15
लेकिन आपको कई निर्देशिकाओं में फ़ाइलों को वितरित करने का एक तरीका है। फाइलसिस्टम एक निर्देशिका में लाखों फाइलों को संग्रहीत करने में उतना अच्छा नहीं है (वास्तव में दस हजारों पहले से ही एक समस्या है)
a_horse_with_no_name

1
मूल प्रश्न का उत्तर नहीं देता। मैं व्यक्तिगत रूप से पोस्टग्रेज में छवियों को संग्रहीत करने के लिए देख रहा हूं क्योंकि मैं एसक्यूएल को अमूर्त की अपनी परत के रूप में चाहता हूं और अपने ext4 फाइल सिस्टम में फ़ाइलों का प्रबंधन नहीं करना चाहता हूं।
sudo

मैं विवादित हूं, यह सवाल का जवाब नहीं देता, लेकिन मैंने इसे गलत ठहराया, क्योंकि यह सवाल के जवाब से बेहतर जवाब है।
एंड्रयू कार

6

यह कोशिश करो । मैंने जेनरेट किए गए PDF दस्तावेज़ों को संग्रहीत करने के लिए बड़े ऑब्जेक्ट बाइनरी (LOB) प्रारूप का उपयोग किया है, जिनमें से कुछ डेटाबेस में 10 + एमबी आकार के थे, और यह आश्चर्यजनक रूप से काम करता था।


2

यदि आपकी छवियां छोटी हैं, तो उन्हें एक सादे पाठ के क्षेत्र में बेस 64 के रूप में संग्रहीत करने पर विचार करें।

कारण यह है कि जबकि base64 में 33% ओवरहेड होता है, संपीड़न के साथ जो ज्यादातर चला जाता है। ( बेस 64 एनकोडिंग का स्पेस ओवरहेड क्या है? ) आपका डेटाबेस बड़ा होगा, लेकिन आपके वेबसर्वर को ग्राहक को भेजने वाले पैकेट नहीं होंगे। Html में, आप एक <img src = ""> टैग में बेसलाइन इनलाइन कर सकते हैं, जो संभवत: आपके ऐप को सरल बना सकता है क्योंकि आपको अलग ब्राउजर में बाइनरी के रूप में छवियों की सेवा नहीं करनी होगी। पाठ के रूप में छवियों को संभालना भी चीजों को सरल करता है जब आपको जसन भेजना / प्राप्त करना होता है, जो बाइनरी को बहुत अच्छी तरह से नहीं संभालता है।

हां, मैं समझता हूं कि आप डेटाबेस में बाइनरी स्टोर कर सकते हैं और इसे डेटाबेस के अंदर और बाहर रास्ते में / पाठ से / में परिवर्तित कर सकते हैं, लेकिन कभी-कभी ORM इसे एक परेशानी बनाते हैं। इसे सिर्फ अपने सभी अन्य क्षेत्रों की तरह सीधे पाठ के रूप में व्यवहार करना सरल हो सकता है।

यह निश्चित रूप से थंबनेल को संभालने का सही तरीका है।

(ओपी की छवियां छोटी नहीं हैं, इसलिए यह वास्तव में उनके सवाल का जवाब नहीं है।)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.