2010-04-07 13 views
14

में स्पैस डेटा का प्रतिनिधित्व करना PostgreSQL में एक स्पैस डेटा मैट्रिक्स का प्रतिनिधित्व करने का सबसे अच्छा तरीका क्या है? दो स्पष्ट तरीकों मैं देख रहा हूँ कर रहे हैं:PostgreSQL

हर कल्पनीय सुविधा (संभावित लाखों) के लिए एक अलग कॉलम के साथ एक एकल तालिका में
  1. स्टोर डेटा, लेकिन अप्रयुक्त सुविधाओं के लिए शून्य का डिफ़ॉल्ट मान के साथ। यह अवधारणात्मक रूप से बहुत सरल है, लेकिन मुझे पता है कि अधिकांश आरडीएमएस कार्यान्वयन के साथ, यह आमतौर पर बहुत अक्षम है, क्योंकि कुल मूल्य कुछ स्थान लेते हैं। हालांकि, मैंने एक लेख पढ़ा है (दुर्भाग्य से इसका लिंक नहीं मिल सकता है) दावा किया है कि पीजी नल मूल्यों के लिए डेटा नहीं लेता है, जिससे यह स्पैस डेटा संग्रहीत करने के लिए बेहतर अनुकूल बनाता है।

  2. अलग "पंक्ति" और "कॉलम" टेबल बनाएं, साथ ही साथ उन्हें जोड़ने के लिए एक मध्यवर्ती तालिका बनाएं और उस पंक्ति पर कॉलम के लिए मान संग्रहीत करें। मेरा मानना ​​है कि यह अधिक पारंपरिक आरडीएमएस समाधान है, लेकिन इसमें अधिक जटिलता और ओवरहेड जुड़ा हुआ है।

मैं भी PostgreDynamic पाया, विरल डेटा बेहतर समर्थन का दावा करता है, जो है, लेकिन मैं तो बस इस सुविधा के लिए एक स्नातकोत्तर कांटा करने के लिए अपने पूरे डेटाबेस सर्वर स्विच करने के लिए नहीं करना चाहती।

क्या कोई अन्य समाधान हैं? मुझे किसका उपयोग करना चाहिए?

उत्तर

7

मन में कुछ समाधान वसंत,

1) समूहों है कि आमतौर पर एक साथ स्थापित कर रहे हैं में अपने सुविधाओं को अलग करें, मुख्य डेटा के लिए एक एक-से-एक विदेशी कुंजी रिश्ते के साथ प्रत्येक समूह के लिए एक तालिका बनाने, केवल

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

3) इसी प्रकार पोस्टग्रेड गतिशील कैसे करता है , अपनी प्राथमिक तालिका में प्रत्येक 'कॉलम' के लिए एक टेबल बनाएं (वे उन तालिकाओं के लिए एक अलग नामस्थान का उपयोग करें), और उन तालिकाओं में डेटा तक पहुंचने और अपडेट करने के लिए सरल बनाने के लिए फ़ंक्शन बनाएं

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

5) प्रकार hstore कि कुंजी-मान जोड़ों धारण कर सकते हैं का एक स्तंभ बनाने के लिए योगदान/hstore मॉड्यूल का उपयोग, और इंडेक्स और अद्यतन

6) liv किया जा सकता है रिक्त फ़ील्ड

+0

इसके अलावा आप फीचरनाम VARCHAR के रूप में एक 'फीचर' प्रकार बना सकते हैं, फीचरव्यू वर्चर (या जो भी मूल्य होना चाहिए) और अपनी प्राथमिक तालिका में फीचर फ़ीचर [] फ़ीचर फ़ील्ड जोड़ें। – MkV

+1

आप ईएवी को "एंटी-पैटर्न" क्यों कहते हैं? गुगलिंग से पता चलता है कि यह ईएवी का एक आम वर्णन है (आमतौर पर अपमानजनक रूप से उपयोग किया जाता है), लेकिन कोई भी क्यों समझाता है। ऐसे कई वैध मामले प्रतीत होते हैं जहां डेटाबेस को चिकित्सा क्षेत्र जैसे स्पैस डेटा स्टोर करने की आवश्यकता होती है, जिससे ईएवी एक उपयुक्त "पैटर्न" बनाते हैं। – Cerin

+1

यह डेटाबेस, पंक्ति स्तर की बाधाओं और संदर्भित अखंडता के सभी फायदे दूर करता है और एक इकाई के लिए एक पंक्ति को वापस करना मुश्किल बनाता है। – MkV

2

एक पूर्ण मूल्य शून्य होने पर कोई स्थान नहीं लेगा। यह ट्यूपल हेडर में बिटमैप में एक बिट ले जाएगा, लेकिन यह परवाह किए बिना होगा।

हालांकि, सिस्टम लाखों कॉलम, अवधि से निपट नहीं सकता है। एक हजार से अधिक सैद्धांतिक अधिकतम है, आईआईआरसी, लेकिन आप वास्तव में अब तक नहीं जाना चाहते हैं।

यदि आपको वास्तव में एक ही तालिका में बहुत से लोगों की आवश्यकता है, तो आपको ईएवी विधि पर जाना होगा, जो मूल रूप से आप (2) में कह रहे हैं।

यदि प्रत्येक प्रविष्टि में केवल अपेक्षाकृत कुछ कुंजी हैं, तो मेरा सुझाव है कि आप "hstore" contrib मॉड्यूल को देखें जो आपको इस प्रकार के डेटा को तीसरे विकल्प के रूप में बहुत कुशलता से स्टोर करने देता है। इसे आगामी 9.0 संस्करण में आगे बढ़ाया गया है, इसलिए यदि आप उत्पादन परिनियोजन से थोड़ी दूर हैं, तो आप उस पर सीधे देखना चाहेंगे। हालांकि, यह 8.4 में भी इसके लायक है। और यह कुछ सुंदर कुशल सूचकांक आधारित लुकअप का समर्थन करता है। निश्चित रूप से देखने लायक है।

10

मैं तुम्हें गणितीय संदर्भ से विरल मैट्रिक्स की सोच रहे हैं यह सोचते कर रहा हूँ बहुत से ई: http://en.wikipedia.org/wiki/Sparse_matrix (भंडारण तकनीकों का वर्णन वहाँ स्मृति भंडारण (तेजी से गणित आपरेशन), नहीं स्थायी भंडारण (कम डिस्क उपयोग के लिए कर रहे हैं)।

चूंकि आमतौर पर सर्वर पक्ष की बजाय क्लाइंट साइड पर इस मैट्रिक्स पर एक एसक्यूएल-एआरआरई [] सबसे अच्छा विकल्प है!

प्रश्न यह है कि मैट्रिक्स की स्पैरिटी का लाभ कैसे लें? यहां कुछ जांच से परिणाम।

सेटअप:

  • Postgres 8.4
  • मैट्रिसेस w/डबल परिशुद्धता में 400 * 400 तत्वों (8 बाइट्स) - मैट्रिक्स
  • 33% गैर शून्य तत्व प्रति> 1.28MiB कच्चे आकार - -> 427kiB मैट्रिक्स प्रति प्रभावी आकार
  • का उपयोग कर औसत निकाला ~ 1000 विभिन्न यादृच्छिक आबादी वाले मैट्रिक्स

प्रतिस्पर्धा तरीके:

  • स्वत: सर्वर साइड सेट भंडारण मुख्य या विस्तारित साथ स्तंभों के संपीड़न पर निर्भर हैं।
  • केवल गैर-शून्य तत्वों के साथ-साथ बिटमैप (bit varying(xx)) बताएं कि मैट्रिक्स में गैर-शून्य तत्वों को कहां खोजें। (एक डबल परिशुद्धता एक बिट से 64 गुना बड़ा है। सिद्धांत रूप में (ओवरहेड्स को अनदेखा कर रहा है) < = 98% गैर-शून्य ;-) हैं।) सर्वर साइड संपीड़न सक्रिय है।
  • मैट्रिक्स में शून्य के साथ शून्य बदलें। (आरडीबीएमएस एनयूएलएस भंडारण में बहुत प्रभावी हैं।) सर्वर साइड संपीड़न सक्रिय है।

(एक 2 सूचकांक सरणी [] है बहुत आशाजनक नहीं और वजह परीक्षण नहीं का उपयोग कर गैर शून्य तत्वों का अनुक्रमण।)

परिणाम:

  • स्वत: संपीड़न
    • कोई अतिरिक्त कार्यान्वयन प्रयास
    • कोई नेटवर्क ट्रैफ़िक कम नहीं किया
    • न्यूनतम संपीड़न भूमि के ऊपर
    • स्थायी भंडारण = 39 कच्चे आकार का%
  • बिटमैप
    • स्वीकार्य कार्यान्वयन प्रयास
    • नेटवर्क यातायात थोड़ा कम किया है; विरलता पर निर्भर
    • स्थायी भंडारण = कच्चे आकार की 33.9%
  • NULLs साथ शून्य बदलें
    • कुछ कार्यान्वयन प्रयास (एपीआई को पता है कहाँ और कैसे में NULLs सेट करने की जरूरत है ARRAY [] जबकि सम्मिलित करें क्वेरी)
    • नेटवर्क यातायात
    • स्थायी भंडारण = 35 वीं की% में कोई परिवर्तन का निर्माण ई कच्चे आकार

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

मैं हमेशा मैट्रिक्स क्रमशः (उदाहरण के लिए पंक्ति-प्रमुख आदेश) और मैट्रिक्स आयाम NxM के लिए दो पूर्णांक कॉलम का उपयोग करने का सुझाव देता हूं। चूंकि अधिकांश एपीआई टेक्स्टुअल एसक्यूएल का उपयोग करते हैं, इसलिए आप नेस्टेड के लिए बहुत सारे नेटवर्क ट्रैफिक और क्लाइंट मेमोरी को सहेज रहे हैं "ARRAY [ARRAY [..], ARRAY [..], ARRAY [..], ARRAY [..], ..]" !!!

Tebas


CREATE TABLE _testschema.matrix_dense 
(
    matdata double precision[] 
); 
ALTER TABLE _testschema.matrix_dense ALTER COLUMN matdata SET STORAGE EXTERN; 


CREATE TABLE _testschema.matrix_sparse_autocompressed 
(
    matdata double precision[] 
); 

CREATE TABLE _testschema.matrix_sparse_bitmap 
(
    matdata double precision[] 
    bitmap bit varying(8000000) 
); 

सम्मिलित सभी तालिकाओं में एक ही मैट्रिक्स। ठोस डेटा कुछ तालिका पर निर्भर करता है। अप्रयुक्त लेकिन आवंटित पृष्ठों के कारण सर्वर पक्ष पर डेटा को न बदलें। या एक वैक्यूम करो।

SELECT 
pg_total_relation_size('_testschema.matrix_dense') AS dense, 
pg_total_relation_size('_testschema.matrix_sparse_autocompressed') AS autocompressed, 
pg_total_relation_size('_testschema.matrix_sparse_bitmap') AS bitmap; 
2

मैं जानता हूँ कि यह एक पुरानी धागा है, लेकिन MadLib, Postgres के लिए एक विरल वेक्टर प्रकार प्रदान करता है कई मशीन सीखने और सांख्यिकीय तरीकों के साथ।