2010-11-09 46 views
4

我注意到我的(純Python)代碼中很大一部分處理表。當然,我有支持基本功能的class Table,但我最終爲它添加了越來越多的功能,例如查詢,驗證,排序,索引等。使用sqlite3 vs自定義表實現的優點和缺點

我想知道刪除它是個好主意我的class Table,並重構代碼使用常規關係數據庫,我將實例化在內存中

這裏是我的想法至今:

  1. 查詢和索引的性能將提高,但Python代碼和單獨的數據庫進程之間的通信可能會比Python函數之間的效率較低。我認爲這是太多的開銷,所以我將不得不使用Python自帶的sqlite並且生活在同一個進程中。我想希望這意味着它是一個純粹的性能增益(以非標準SQL定義和sqlite的有限功能爲代價)。

  2. 使用SQL,我將獲得比我想要編碼自己更強大的功能。似乎有一個明顯的優勢(即使使用sqlite)。

  3. 我不需要調試我自己的表的實現,但在SQL中調試錯誤很難,因爲我不能放置斷點或輕鬆打印臨時狀態。我不知道如何判斷我的代碼可靠性和調試時間的整體影響。

  4. 該代碼將更容易閱讀,因爲代替調用我自己的自定義方法,我會編寫SQL(每個需要維護此代碼的人都知道SQL)。但是,處理數據庫的Python代碼可能比使用純Python class Table的代碼更醜陋,也更復雜。再說一遍,我不知道哪個更好。

對上述的任何更正或其他任何我應該考慮的問題?

回答

5

SQLite不能在單獨的進程中運行。所以你實際上沒有任何額外的IPC開銷。但是,IPC開銷並不是那麼大,無論如何,特別是在例如UNIX套接字中。如果您需要多個編寫器(同時向數據庫寫入多個進程/線程),鎖定開銷可能會更糟,並且MySQL或PostgreSQL的性能會更好,尤其是在同一臺計算機上運行時。所有這三個數據庫都支持的基本SQL是相同的,所以基準測試並不是那麼痛苦。

您通常不必在SQL語句上執行與您自己的實現相同類型的調試。 SQLite的工作原理,已經很好地調試了。這是不太可能的,你永遠不得不調試「好吧,該行存在,爲什麼數據庫沒有找到它?」並追蹤索引更新中的錯誤。調試SQL與過程代碼完全不同,而且實際上只會發生非常複雜的查詢。

至於調試你的代碼,你可以很容易地集中你的SQL調用,並添加跟蹤來記錄你正在運行的查詢,返回的結果等。Python的SQLite接口可能已經有這個(不知道,我通常使用Perl)。將現有的Table類作爲SQLite的包裝可能是最簡單的。

我強烈建議不要重新發明輪子。 SQLite將具有更少的錯誤,併爲您節省大量時間。(你可能也想看看Firefox最近轉向使用SQLite來存儲歷史記錄等,我認爲他們得到了一些非常顯着的加速)

此外,SQLite的優化​​的C實現可能是相當的比任何純Python實現快一點。

+0

是的,這就是爲什麼我認爲sqlite是內存數據庫的唯一合理選擇。我不知道是否還有其他性能問題;我不確定IPC甚至可能不會成爲問題(這會讓我考慮更復雜的數據庫而不是sqlite)。 – max 2010-11-09 17:57:07

+1

我不是故意調試sqlite;我打算調試我自己的代碼:我認爲當我使用自己的'class Table'而不是sqlite時,可以更容易地看到表中的內容並在各種條件下中斷。至於多名作者,你能澄清一下你的意思嗎(我的代碼當然是單線程的)。 – max 2010-11-09 18:02:38

+0

@max:我想我已經更新了我的答案以回答這個問題...... – derobert 2010-11-09 18:08:18

0

如果你在做數據庫工作,使用數據庫,如果你不是,那麼不要。使用表格,它聽起來就像你。我建議使用ORM來使其更加pythonic。 SQLAlchemy是最靈活的(儘管它不僅僅是一個ORM)。

+1

不,我沒有做數據庫工作,因爲沒有數據庫作爲我的輸入或輸出程序。我只需要在我的代碼的臨時步驟中創建,排序,篩選和查詢很多表。 – max 2010-11-09 17:59:28

+0

但有一個「基礎」的數據。 – 2010-11-09 18:44:14

+0

@max「創建,排序,過濾和查詢多個表」意味着「數據庫」。缺乏持久意味着「臨時」。臨時數據庫。 – 2010-11-09 19:26:22

4

您可以嘗試使用與您的類表相同的接口創建一個sqlite包裝器,以便保持代碼清潔並獲得sqlite性能。

+1

對於sqlite包裝想法+1 – max 2010-11-09 18:17:55

相關問題