2010-11-15 16 views
6

我採取的是類似於典型的數據庫表中的類:如何實現數據庫樣式表在Python

  • 已命名的列和無名行
  • 有一個主鍵由我可以引用行
  • 支持通過主鍵和列標題進行檢索和分配
  • 可以被要求爲任何列添加唯一索引或非唯一索引,從而允許快速檢索具有給定行的行(或行集合)在該列中的值
  • 刪除一行很快,實現爲「軟刪除」:該行保持物理狀態,但被標記爲刪除並且不會在任何後續檢索操作中顯示
  • 添加列很快
  • 行很少添加
  • 列被刪除很少

我決定實現類,而不是直接使用包裝周圍源碼。

什麼是一個好的數據結構使用?


就像一個例子,我想到的一種方法是字典。它的鍵是表的主鍵列中的值;其值是以下列方式之一實施的行:

  1. 作爲列表。列號映射到列標題中(使用一個方向的列表和另一個方向的地圖)。這裏,檢索操作首先將列標題轉換爲列號,然後在列表中找到相應的元素。

  2. 作爲字典。列標題是這本詞典的關鍵。

不能確定兩者的優點/缺點。


我想要寫我自己的代碼的原因是:

  • 我需要跟蹤行刪除。也就是說,在任何時候我都希望能夠報告哪些行被刪除以及什麼「原因」(「原因」被傳遞給我的刪除方法)。
  • 我需要建立索引期間的一些報告(例如,當一個非唯一索引正在修建,我要檢查一定的條件,如果他們違反報告)
+0

爲什麼要這樣做,而不是使用現有的DBMS? – delnan 2010-11-15 19:57:05

+1

特別是,爲什麼不使用'sqlite'的包裝? – katrielalex 2010-11-15 20:03:36

+0

@delnan @katrielalex:剛剛編輯我的問題,給出幾個原因。也許有辦法用sqlite包裝來做到這一點? – max 2010-11-15 20:05:50

回答

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() 
     ... 

軟刪除可以通過具有softdelete柱(布爾來實現類型)。 同樣,您可以有一個列來存儲刪除的原因。 解除刪除只需更新行並更改softdelete值。 可以使用SQL條件WHERE softdelete != 1來選擇尚未刪除的行。

你可以寫一個verify方法來驗證您的數據條件得到滿足。您可以在您的build_index方法中調用該方法。

另一種替代方法是使用結構化掩蔽的陣列的numpy的。

很難說什麼是最快的。也許唯一可以確定的方法是編寫代碼,並用timeit編寫真實世界數據的基準。

+0

我喜歡'softdelete'專欄的想法。我不認爲自己可以執行'verify'方法,因爲在構建索引時逐行檢查了我的條件;但如果我可以依靠sqlite而不是自定義類,它可能是一個小的代價。我也有興趣瞭解'MaskedArray',也從未聽說過它。 – max 2010-11-15 22:15:47

2

我會考慮建立一個字典,鍵是是元組或列表。例如:my_dict(("col_2", "row_24"))會給你這個元素。從那裏開始,這對於編寫'get_col'和'get_row'方法,以及前兩個方法中的'get_row_slice'和'get_col_slice'來說非常容易(如果對於非常大的數據庫來說速度不是非常快),以訪問您的方法。

使用這樣的整個字典將有兩個優點。1)獲取單個元素將比您提出的兩種方法更快; 2)如果你想在你的列中有不同數量的元素(或缺少的元素),這將使它非常簡單和高效的存儲。

只是一個想法:)我會很好奇,想看看哪些軟件包的人會建議!

乾杯

+0

有趣。對我來說,這看起來更快,但我不確定:可以想象,獲取列表元素可能與爲元組計算散列而不是單個值所需的額外工作一樣快。順便說一句,我只關心時間,而不是記憶,效率。 – max 2010-11-15 20:22:04

+0

然後當表格變大時,字典肯定會更快。在一百萬個元素的列表中,您需要先搜索平均50萬個元素,然後才能找到合適的元素。使用散列表,因此是字典,您需要搜索最多20個元素以找到正確的元素。乾杯! – Morlock 2010-11-15 21:12:54

+0

我同意,但是當我說「列表」時,我打算使用字典將列名轉換爲O(1)訪問的列表索引。剛開始使用字典比較容易。 – max 2010-11-16 16:49:53

0

你真的應該使用SQLite。

爲了您的第一個原因(跟蹤缺失的原因),你可以很容易地通過具有第二表,你「移動」行上刪除實現這一點。原因可以在該表的其他列中跟蹤,或者可以加入另一個表中。如果不需要刪除原因,那麼您甚至可以在源表上使用觸發器來複制要刪除的行,和/或具有可以得到原因的用戶定義函數。

索引原因在某種程度上被限制等包括在內,但我不能直接解決這個問題沒有更多的細節。

相關問題