Sqlite資料庫刪除大量資料後的擦屁股工作

2021-05-23 11:31:27 字數 3531 閱讀 1491

sqlce

實在是太慢了,在執行速率和

sqlite

沒法比。

所以在專案的下乙個版本中,準備用

sqlite

替換掉sqlce。

事前做嘗試工作,畢竟沒有用過

sqlite。

結果試了試確實不錯,有兩點很滿意。

第一,執行速率就不用說了,眾所周一的比

sqlce快

第二,或許對別人來說是個雞肋,但是我這個還挺需要的(是我想出來的笨解決方案,有什麼好方案,可以幫我提提意見)

什麼優點呢?壓縮率。

不知道有沒有人知道用

winzip

給sqlite

的.db

檔案打過包?壓縮率

其實是很高的。

舉個例子,同樣的兩個資料庫,乙個

sqlce

的.sdf

檔案,乙個

sqlite

的.db

檔案。

其中的資料內容完全相同,在硬碟上的占用空間分別是

sqlce:3,207,168byte,sqlite:3,117,056byte

用winrar

進行壓縮,結果分別是

sqlce:3,158,016byte,sqlite:1,159,168byte

可以看到,

sqlce

壓縮後,資料量基本上沒有改變。而

sqlite

壓縮後,資料量變成了原來的將近三分之一。

這意味著什麼,這意味著在網路上的傳輸資料量,傳輸時間大大節省了。 按照

」中國移不動

「的費率,大家可以省很多話費去交人頭稅的。 按照

」中國聯不通

「的網路,可以大大節省傳輸時間,減少聯不通的概率。

呵呵,其實主要是我所在的專案,每次做資料庫同步的時候,如果要在手機端迴圈插入更新一萬條資料,耗時太長,是不能容忍的。於是我愚昧的決定把資料庫檔案傳回伺服器,在伺服器端更新後然後再傳回給手機。於是這個壓縮的問題對我來說很重要。

其次壓縮對我來說還有一點很重要,我是通過

soap

的方式傳遞資料的。就通過

xml,這個方法很笨但是實現起來簡單。問題就在於將

3m以上的檔案序列化到

xml裡面,傳遞是會無端的出問題。

我就在一台還沒有發售的機器上遇到過

stringbuilder

的錯誤,

soap

底層對xml

處理是用到了

stringbuilder

,這個時候就出過問題。我考慮就是因為

3m的資料太大了。(只是猜測,我下午專門對這個機器進行測試)

所以以上種種原因,我需要乙個在網路上傳輸最「輕量」的方式。無疑就是壓縮了。

說了這麼多,沒進主題,我的主題是給

sqlite

在刪除資料後擦屁股。

大家或許發現了,當你在

sqlite

中刪除了大量資料後,資料庫檔案的大小還是那樣,沒有變。

就用我的專案來說,

3m的資料刪除後,

sqlite

的.db

檔案依然是

3m,而我要的結果實際上只有

35k,在壓縮一下也就10幾

k了。為什麼會出現這個問題,

sqlce

的.sdf

檔案是即刪即減的。

原因是:

當你從sqlite

刪除資料後,未使用的磁碟空間被新增到乙個內在的

」空閒列表

」中用於儲存你下次插入的資料。磁碟空間並沒有丟失。但是也不向作業系統返回磁碟空間。(嘿嘿,

sqlite.org

的faq

中提到過這個問題)

解決方法:兩種 一,

在資料刪除後,手動執行

vacuum

命令,執行方式很簡單

objsqlhelper.executenonquery(commandtype.text, "vacuum")

vacuum

命令會清空「空閒列表」,把資料庫尺寸壓縮到最小。但是要耗費一些時間。

fqa裡面說,在

linux

的環境下,大約

0.5秒

/m。並且要使用兩倍於資料庫檔案的空間。

我憎恨此

fqa,他只說系統環境,不說機器硬體環境。我在測試手機上執行用了將近

13秒時間壓縮了將近

3m的空間。至於它所占用的另一部分空間,是生成了乙個

.db-journal

字尾名的臨時檔案。(這個問題對我現在來說是無所謂的。)

二,在資料庫檔案建成中,將

auto_vacuum

設定成「1」。

注意:只有在資料

庫中未建任何表

時才能改

變auto-vacuum標記。

試圖在已有表的情況下修改不會

導致報錯。

cmd.commandtext = "pragma auto_vacuum = 1;"

cmd.execut

enonquery()

當開啟auto-vacuum

,當提交乙個從資料庫中

刪除除資料的

事物時,資料庫檔案

自動收縮。 資料

庫會在內部存

儲一些資訊以便支援

這一功能,

這使得資料

庫檔案比不開啟

該選項時

稍微大一些。

我的表結構,不含任何資料是,資料庫檔案大小是

25k左右,開了

auto_vacuum

之後是26k。

插入執行基礎資料後,檔案變成

35k,開了

auto_vacuum

之後是36k。

變化不大,無所謂。

但是第二個方法同樣有缺點,只會從資料庫檔案中截斷空閒列表中的頁,

而不會**資料庫中的碎片,也不會像

vacuum

命令那樣重新整理資料庫內容。實際上,由於需要在資料庫檔案中移動頁,

auto-vacuum 

會產生更多的碎片。而且,在執行刪除操作的時候,也有那個

.db-journal

檔案產生。

要使用auto-vacuum

,需要一些前題條件。

資料庫中需要儲存一些額外的資訊以記錄它所跟蹤的每個資料庫頁都找回其指標位置。

所以,auto-vacumm 

必須在建表之前就開啟。在乙個表建立之後,

就不能再開啟或關閉

auto-vacumm。

其實按照執行時間上的比較,兩個在做了大刪除操作後,從

3m變到

35k的時間其實差不多,執行

vacuum

命令稍微長一點,但是也長不了多少,相對而言,這種一點點的長可以忽略不計。 加上

auto

的方式對碎片的造成情況,如果資料交換次數多的話,這種方式很不合適。

還是決定用第一種方式,在大資料刪除後,向伺服器送信前。執行

vacuum

命令。這樣做比較划算。

C 建立刪除SQLite資料庫

sqlite 是檔案型的資料庫,建立很簡單,直接指定乙個資料庫檔名,字尾名不一定非得是 sqlite 在開發時字尾經常命名為 db 一 建立資料庫 在c 中,執行 sqliteconnection.open 就會建立乙個空的指定名字的資料庫檔案。由於它是檔案型的,我們也可以直接用 system.io...

使用SQLite資料庫儲存資料 4 刪除資料記錄

刪除資料記錄 當從uitableview中刪除一行記錄時,將呼叫commiteditingstyle方法。void tableview uitableview tableview commiteditingstyle uitableviewcelleditingstyle editingstyle ...

SQLite資料庫掃盲

今天注意到 sqlite 3.6.11 上個月發布的 增加了乙個我期待已久的 online backup 介面,激動之餘就順便和大夥兒聊一下sqlite資料庫。本帖權當是sqlite掃盲,如果你對sqlite已經很熟悉,本文就不必再看了。技術上的優點和特性 sqlite是乙個輕量級 跨平台的關係型資...