SQLite這么嬌小可愛,不多了解點都不行啊

jopen 9年前發布 | 15K 次閱讀 SQLite

    在我眼里,MySQL 和 Oracle 是這樣的

SQLite這么嬌小可愛,不多了解點都不行啊

SQLite這么嬌小可愛,不多了解點都不行啊

而 SQLite 在是這樣的

SQLite這么嬌小可愛,不多了解點都不行啊

所以這么萌的數據庫,我真的應該多了解她的。

簡介

SQLite,是一款輕型的數據庫,是遵守 ACID 的關系型數據庫管理系統。它的設計目標是嵌入式的,目前 Android 和 iOS 的設備內置的都是 SQLite 數據庫。SQLite 雖然嬌小,但也支持事務和多數的 SQL92 標準。

主要特點

  • Zero-Configuration 無需安裝和管理配置。
  • Serverless 無需服務器支持。
  • Single Database File 數據文件存儲在一個單一的磁盤文件。
  • Stable Cross-Platform Database File 數據庫文件格式跨平臺,無論是大小端,或者是 32bit 或 64bit 機器都沒有關系
  • Compact 完整特性的 SQLite 編譯出來在 500KiB 左右,裁剪特性甚至可以得到低于 300KiB 的庫(當前版本 3.8.11.1)。
  • Manifest typing 可以聲明數據庫字段類型,但是字段存儲的類型實際的存儲類型和實際值相關,單獨的一個字段可能包含不同存儲類的值。
  • Variable-length records 可變長度記錄,例如你存儲一個字符到 VARCHAR (100) 的列,實際需要的存儲空間一個字符加一個字節的存儲空間。
  • SQL statements compile into virtual machine code SQL 語句會被編譯成虛擬機代碼,這種虛擬機代碼直白可讀,便于調試。
  • Public domain 完全開源。
  • SQL language extensions
  • </ul>

    主要缺點

    • SQLite 只提供數據庫級的鎖定,所以不支持高并發。
    • 不支持存儲過程。
    • SQLite 沒有用戶帳戶概念,而是根據文件系統確定所有數據庫的權限。這會使強制執行存儲配額發生困難,強制執行用戶許可變得不可能。
    • </ul>

      如果只在移動設備使用 SQLite,那么他的優點足夠好,并且缺點不明顯,所以大叔 MySQL 走開。SQLite 妹妹快過來。

      事務與鎖( < 3.7.0)

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

      SQLite 有 5 個不同的鎖狀態

      1. UNLOCKED(未加鎖)
      2. SHARED(共享)
      3. RESERVED(保留)
      4. PENDING(未決)
      5. EXCLUSIVE(排它)
      6. </ol>

        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(排它)
        4. </ol>

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

          SQLite這么嬌小可愛,不多了解點都不行啊

          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這么嬌小可愛,不多了解點都不行啊

          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行為更容易被預測
          4. </ol>

            缺點

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

              </li>

            2. 每個數據庫現在對應 3 個文件:.db,-wal,-shm。

              </li>

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

              </li>

            4. 3. 7.0 之前的 SQLite 無法識別啟用了 WAL 機制的數據庫文件。

              </li>

            5. WAL 引入的兼容性問題。在啟用了 WAL 之后,數據庫文件格式的版本號由 1 升級到了2,因此,3.7.0 之前的 SQLite 無法識別啟用了 WAL 機制的數據庫文件。禁用 WAL 會使數據庫文件格式的版本號恢復到1,從而可以被 SQLite 3.7.0 之前的版本識別。

              </li>

            6. WAL 引入的性能問題。在一般情況下,WAL 會提高 SQLite 的事務性能;但是在某些極端情況下,卻會導致 SQLite 事務性能的下降。

              • 在事務執行時間較長或者要修改的數據量達到 GB 級的時候,WAL 文件會被占用,它會暫時阻止 checkpoint 的執行(checkpoint 會清空 WAL 文件),這將導致 WAL 文件變得很大,增加尋址時間,最終導致讀寫性能的下降。
              • 當 checkpoint 執行的時候,會降低當時的讀寫性能,因此,WAL 可能會導致周期性的性能下降
              • </ul> </li> </ol>

                來自: supermao.cn
                 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
                 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
                 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!