SQLite這麼嬌小可愛,很少了解點都不行啊

在我眼裏,MySQL和Oracle是這樣的數據庫

SQLite,MySQL,Oracle

 

SQLite,MySQL,Oracle

而SQLite在是這樣的服務器

SQLite,MySQL,Oracle

因此這麼萌的數據庫,我真的應該多瞭解她的。併發

 

簡介

 

SQLite,是一款輕型的數據庫,是遵照ACID的關係型數據庫管理系統。它的設計目標是嵌入式的,目前Android和iOS的設備內置的都是SQLite數據庫。less

SQLite雖然嬌小,但也支持事務和多數的SQL92標準。dom

 

主要特色

 

1. Zero-Configuration 無需安裝和管理配置。高併發

 

2. Serverless 無需服務器支持。性能

 

3. Single Database File 數據文件存儲在一個單一的磁盤文件。設計

 

4. Stable Cross-Platform Database File 數據庫文件格式跨平臺,不管是大小端,或者是32bit或64bit機器都沒有關係調試

 

5. Compact 完整特性的SQLite編譯出來在500KiB左右,裁剪特性甚至能夠獲得低於300KiB的庫(當前版本3.8.11.1)。code

 

6. Manifest typing 能夠聲明數據庫字段類型,可是字段存儲的類型實際的存儲類型和實際值相關,單獨的一個字段可能包含不一樣存儲類的值。

 

7. Variable-length records 可變長度記錄,例如你存儲一個字符到VARCHAR(100) 的列,實際須要的存儲空間一個字符加一個字節的存儲空間。

 

8. SQL statements compile into virtual machine code SQL語句會被編譯成虛擬機代碼,這種虛擬機代碼直白可讀,便於調試。

 

9. Public domain 徹底開源。

 

10. SQL language extensions

 

主要缺點

 

1. SQLite 只提供數據庫級的鎖定,因此不支持高併發。

 

2. 不支持存儲過程。

 

3. SQLite 沒有用戶賬戶概念,而是根據文件系統肯定全部數據庫的權限。這會使強制執行存儲配額發生困難,強制執行用戶許可變得不可能。

 

若是隻在移動設備使用SQLite,那麼他的優勢足夠好,而且缺點不明顯,因此大叔MySQL走開。SQLite妹妹快過來╭(╯3╰)╮。

 

事務與鎖( < 3.7.0)

 

SQLite的事務和鎖是很重要的概念。

 

 

SQLite有5個不一樣的鎖狀態

 

1. UNLOCKED(未加鎖)

 

2. SHARED(共享)

 

3. RESERVED(保留)

 

4. PENDING(未決)

 

5. EXCLUSIVE(排它)

 

SQLite有一個加鎖表,記錄數據庫鏈接的鎖狀態。每一個數據庫鏈接在同一時刻只能處於其中一個鎖狀態。每種狀態(UNLOCKED)都有一種鎖與之對應。

 

 
 

數據庫鏈接最初處於UNLOCKED狀態,在此狀態下,鏈接尚未存取數據庫。當鏈接到了一個數據庫,甚至已經用BEGIN開始了一個事務時,鏈接都還處於UNLOCKED狀態。爲了可以從數據庫中讀取數據,鏈接必須必須進入SHARED狀態,也就是說首先要得到一個SHARED鎖。多個鏈接能夠同時得到並保持共享鎖,也就是說多個鏈接能夠同時從同一個數據庫中讀數據,SQLite是支持併發讀取數據的。

 

 

一個鏈接想要寫數據庫,它必須首先得到一個RESERVED鎖。一個數據庫上同時只能有一個RESERVED鎖,保留鎖能夠與共享鎖共存,RESERVED鎖即不阻止其它擁有SHARED鎖的鏈接繼續讀數據庫,也不阻止其它鏈接得到新的SHARED鎖。 一旦一個鏈接得到了RESERVED鎖,它就能夠將數據寫入緩衝區,而不是實際地寫到磁盤。 當鏈接想要提交修改(或事務)時,須要得到PENDING鎖,以後鏈接就不能再得到新的SHARED鎖了,但已經擁有SHARED鎖的鏈接仍然能夠繼續正常讀數據庫。當全部其它SHARED鎖都被釋放時,擁有PENDING鎖的鏈接就能夠將其鎖提高至EXCLUSIVE鎖,此時就能夠將之前對緩衝區所作的修改寫到數據庫文件。因此SQLite是不支持併發寫的。

 

事務

 

SQLite有三種不一樣的事務

 

1. DEFERRED(推遲)

 

2. MMEDIATE(當即)

 

3. EXCLUSIVE(排它)

 

事務類型在BEGIN命令中指定:

SQLite,MySQL,Oracle

 

DEFERRED

 

一個DEFERRED事務不獲取任何鎖(直到它須要鎖的時候),BEGIN語句自己也不會作什麼事情——它開始於UNLOCK狀態。默認狀況下就是這樣的,若是僅僅用BEGIN開始一個事務,那麼事務就是DEFERRED的,同時它不會獲取任何鎖;當對數據庫進行第一次讀操做時,它會獲取SHARED鎖;一樣,當進行第一次寫操做時,它會獲取RESERVED鎖。

 

MMEDIATE

 

由BEGIN開始的IMMEDIATE事務會嘗試獲取RESERVED鎖。若是成功,BEGIN IMMEDIATE保證沒有別的鏈接能夠寫數據庫。可是,別的鏈接能夠對數據庫進行讀操做;可是,RESERVED鎖會阻止其它鏈接的BEGIN IMMEDIATE或者BEGIN EXCLUSIVE命令,當其它鏈接執行上述命令時,會返回SQLITE_BUSY錯誤。這時你就能夠對數據庫進行修改操做了,可是你還不能提交,當你COMMIT時,會返回SQLITE_BUSY錯誤,這意味着還有其它的讀事務沒有完成,得等它們執行完後才能提交事務。

 

EXCLUSIVE

 

EXCLUSIVE事務會試着獲取對數據庫的EXCLUSIVE鎖。這與IMMEDIATE相似,可是一旦成功,EXCLUSIVE事務保證沒有其它的鏈接,因此就可對數據庫進行讀寫操做了。

 

死鎖

若是兩個以BEGIN DEFERRED開始事務的鏈接都處於SHARED狀態,而且都在等待對方結束SHARED從而進入RESERVED的話,就會進入死鎖狀態。因此BEGIN DEFERRED開始的事務是有可能產生死鎖的.

 

Write-Ahead Logging ( >=3.7.0 )

 

SQLite 3.7.0以前是不支持寫的時候讀得。爲了可以讀得時候寫,引入了Write-Ahead Logging(WAL)機制,這樣能夠支持一個寫和多個讀併發。

在引入WAL機制以前,SQLite使用rollback journal機制實現原子事務。

SQLite,MySQL,Oracle

rollback journal機制的原理是:在修改數據庫文件中的數據以前,先將修改所在分頁中的數據備份在另一個地方,而後纔將修改寫入到數據庫文件中;若是事務失敗,則將備份數據拷貝回來,撤銷修改;若是事務成功,則刪除備份數據,提交修改。

 

WAL機制的原理是:修改並不直接寫入到數據庫文件中,而是寫入到另一個稱爲WAL的文件中;若是事務失敗,WAL中的記錄會被忽略,撤銷修改;若是事務成功,它將在隨後的某個時間被寫回到數據庫文件中,提交修改。

 

同步WAL文件和數據庫文件的行爲被稱爲checkpoint(檢查點),它由SQLite自動執行,默認是在WAL文件積累到1000頁修改的時候;固然,在適當的時候,也能夠手動執行checkpoint,SQLite提供了相關的接口。執行checkpoint以後,WAL文件會被清空。

 

在讀的時候,SQLite將在WAL文件中搜索,找到最後一個寫入點,記住它,並忽略在此以後的寫入點(這保證了讀寫和讀讀能夠並行執行);隨後,它肯定所要讀的數據所在頁是否在WAL文件中,若是在,則讀WAL文件中的數據,若是不在,則直接讀數據庫文件中的數據。

 

在寫的時候,SQLite將之寫入到WAL文件中便可,可是必須保證獨佔寫入,所以寫寫之間不能並行執行。

 

WAL在實現的過程當中,使用了共享內存技術,所以,全部的讀寫進程必須在同一個機器上,不然,沒法保證數據一致性。

 

優勢

 

1. 讀和寫能夠徹底地併發執行,不會互相阻塞(可是寫之間仍然不能併發)。

 

2. WAL在大多數狀況下,擁有更好的性能(由於無需每次寫入時都要寫兩個文件)。

 

3. 磁盤I/O行爲更容易被預測

 

缺點

 

  1. 1. 訪問數據庫的全部程序必須在同一主機上,且支持共享內存技術。

  2. 2. 每一個數據庫如今對應3個文件:.db,-wal,-shm。

  3. 3. 當寫入數據達到GB級的時候,數據庫性能將降低。

  4. 4. 3.7.0以前的SQLite沒法識別啓用了WAL機制的數據庫文件。

  5. 5. WAL引入的兼容性問題。在啓用了WAL以後,數據庫文件格式的版本號由1升級到了2,所以,3.7.0以前的SQLite沒法識別啓用了WAL機制的數據庫文件。禁用WAL會使數據庫文件格式的版本號恢復到1,從而能夠被SQLite 3.7.0以前的版本識別。

  6. 6. WAL引入的性能問題。在通常狀況下,WAL會提升SQLite的事務性能;可是在某些極端狀況下,卻會致使SQLite事務性能的降低。

    ①在事務執行時間較長或者要修改的數據量達到GB級的時候,WAL文件會被佔用,它會暫時阻止checkpoint的執行(checkpoint會清空WAL文件),這將致使WAL文件變得很大,增長尋址時間,最終致使讀寫性能的降低。

  7. ②當checkpoint執行的時候,會下降當時的讀寫性能,所以,WAL可能會致使週期性的性能降低

原文連接:http://www.jointforce.com/jfperiodical/article/997?f=jf_tg_bky

原文做者:空之境界

相關文章
相關標籤/搜索