2010-11-15 9 views
6

में डेटाबेस शैली तालिका लागू करने के लिए मैं एक वर्ग कि एक विशिष्ट डेटाबेस तालिका से मिलता-जुलता को लागू कर रहा हूँ:कैसे अजगर

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

मैं वर्ग को लागू करने के लिए सीधे बजाय SQLite के चारों ओर एक आवरण का उपयोग का निर्णय लिया।

उपयोग करने के लिए एक अच्छी डेटा संरचना क्या होगी?


बस एक उदाहरण के रूप में, एक दृष्टिकोण के बारे में मैं सोच रहा था एक शब्दकोश है। इसकी कुंजी तालिका के प्राथमिक कुंजी कॉलम में मान हैं; इसके मूल्य इन तरीकों में से एक में लागू पंक्तियां हैं:

  1. सूचियों के रूप में। स्तंभ संख्या कॉलम शीर्षक में मैप की जाती है (एक दिशा के लिए एक सूची का उपयोग करके और दूसरे के लिए एक मानचित्र का उपयोग कर)। यहां, एक पुनर्प्राप्ति ऑपरेशन पहले कॉलम शीर्षक को कॉलम नंबर में परिवर्तित करेगा, और फिर सूची में संबंधित तत्व ढूंढें।

  2. शब्दकोश के रूप में। कॉलम शीर्षक इस शब्दकोश की कुंजी हैं।

दोनों के पेशेवरों/विपक्ष के बारे में निश्चित नहीं है।


कारणों मैं अपने खुद के कोड लिखना चाहते हैं:

  • मैं पंक्ति विलोपन को ट्रैक करने की जरूरत है। यही है, किसी भी समय मैं यह रिपोर्ट करने में सक्षम होना चाहता हूं कि किस पंक्तियों को हटाया गया है और किस कारण से (कारण "मेरी हटा विधि को" कारण "पास किया गया है)।
  • मैं अनुक्रमण के दौरान कुछ रिपोर्टिंग की जरूरत है (उदाहरण के लिए, जबकि एक गैर-अद्वितीय सूचकांक बनाया जा रहा है, मैं कुछ शर्तों की जाँच करें और रिपोर्ट यदि वे का उल्लंघन होता है करना चाहते हैं)
+0

मौजूदा डीबीएमएस का उपयोग करने के बजाय ऐसा क्यों करें? – delnan

+1

विशेष रूप से, 'sqlite' के आस-पास एक रैपर का उपयोग क्यों न करें? – katrielalex

+0

@delnan @ katrielalex: कुछ कारण देने के लिए बस मेरे प्रश्न को संपादित किया। शायद स्क्लाइट रैपर के साथ ऐसा करने का कोई तरीका है? – max

उत्तर

2

आप एक वर्ग जो हुड के नीचे एक में स्मृति SQLite तालिका का उपयोग करता बनाने पर विचार कर सकता है:

import sqlite3 

class MyTable(object): 
    def __init__(self): 
     self.conn=sqlite3.connect(':memory:') 
     self.cursor=self.conn.cursor() 
     sql='''\ 
      CREATE TABLE foo ... 
     ''' 
     self.execute(sql) 
    def execute(self,sql,args): 
     self.cursor.execute(sql,args) 
    def delete(self,id,reason): 
     sql='UPDATE table SET softdelete = 1, reason = %s where tableid = %s' 
     self.cursor.execute(sql,(reason,id,)) 
    def verify(self): 
     # Check that certain conditions are true 
     # Report (or raise exception?) if violated 
    def build_index(self): 
     self.verify() 
     ... 

मुलायम हटाना (bool के softdelete स्तंभ होने से लागू किया जा सकता प्रकार)। इसी प्रकार, आपके पास हटाने के कारण को संग्रहीत करने के लिए एक कॉलम हो सकता है। अनदेखा करने में पंक्ति को अपडेट करने और softdelete मान बदलने में शामिल होगा। हटाए गए पंक्तियों को चुनना SQL स्थिति WHERE softdelete != 1 के साथ प्राप्त किया जा सकता है।

आप अपने डेटा की शर्तों को सत्यापित करने के लिए verify विधि लिख सकते हैं। और आप उस विधि को अपने build_index विधि से कॉल कर सकते हैं।

एक और विकल्प एक सुस्त संरचित मुखौटा सरणी का उपयोग करना है।

यह कहना मुश्किल है कि सबसे तेज़ क्या होगा। शायद बताने का एकमात्र निश्चित तरीका समय-समय पर वास्तविक दुनिया डेटा पर प्रत्येक और बेंचमार्क के लिए कोड लिखना होगा।

+0

मुझे 'softdelete' कॉलम विचार पसंद है। मुझे नहीं लगता कि मैं 'सत्यापन' विधि कर सकता हूं क्योंकि इंडेक्स बनने के दौरान मेरी स्थितियों की जांच की जा रही थी (पंक्ति द्वारा पंक्ति); लेकिन अगर मैं कस्टम क्लास के बजाय स्क्लाइट पर भरोसा कर सकता हूं तो यह भुगतान करने के लिए एक छोटी सी कीमत हो सकती है। और मुझे 'मास्कडअरे' के बारे में भी सीखना था, इससे पहले कभी नहीं सुना था। – max

2

मैं कुंजी के साथ एक शब्दकोश के निर्माण पर विचार होता है कि tuples या सूचियां हैं। उदाहरण: my_dict(("col_2", "row_24")) आपको यह तत्व मिलेगा। वहां से शुरू होने पर, यह बहुत आसान होगा (यदि बहुत बड़े डेटाबेस के लिए बेहद तेज़ नहीं है) 'get_col' और 'get_row' विधियों को लिखने के साथ-साथ 'get_row_slice' और 'get_col_slice' को पहले से प्राप्त करने के लिए आपके पिछले तक पहुंच प्राप्त करने के लिए तरीकों।

इस तरह के पूरे शब्दकोश का उपयोग करने से 2 फायदे होंगे।1) एक एकल तत्व प्राप्त करना आपके 2 प्रस्तावित तरीकों से तेज़ होगा; 2) यदि आप अपने कॉलम में विभिन्न तत्वों (या गायब तत्व) रखना चाहते हैं, तो यह इसे बेहद आसान और स्मृति कुशल बना देगा।

बस एक विचार :) मैं यह जानकर उत्सुक रहूंगा कि लोग कौन से पैकेज सुझाएंगे!

चीयर्स

+0

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

+0

तब तालिका एक बड़ी हो जाएगी जब टेबल बड़ा हो जाएगा। दस लाख तत्वों की एक सूची में, आपको सही पहुंचने से पहले औसत आधे मिलियन तत्वों की खोज करने की आवश्यकता है। हैश टेबल के साथ, इसलिए एक शब्दकोश, आपको सही खोजने के लिए अधिकतम 20 तत्वों को खोजने की आवश्यकता है। चीयर्स! – Morlock

+0

मैं सहमत हूं, लेकिन जब मैंने कहा "सूची" मैं कॉलम नाम को ओ (1) एक्सेस के लिए सूची सूचकांक में कनवर्ट करने के लिए एक शब्दकोश का उपयोग करना चाहता था। शुरू करने के लिए बस शब्दकोश का उपयोग करना आसान है। – max

0

आपको वास्तव में SQLite का उपयोग करना चाहिए।

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

इंडेक्सिंग कारण कुछ हद तक बाधाओं से ढका हुआ है लेकिन मैं बिना किसी विवरण के सीधे इसे संबोधित नहीं कर सकता।