2016年應該使用SQLite的5大原因
本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
什麼?你還不知道SQLite?那麼我告訴你,SQLite是一個了不起的資料庫,能夠在實際生產環境中做真正的工作。在這篇文章中,我將簡要說明5個我認為你應該在2016年使用SQLite的原因。
1.管理簡單
你以前管理過Postgres資料庫嗎?為了確保資料庫伺服器的正確配置(共享緩衝區,有效快取大小,work mem,維護work mem,wal緩衝區…),你需要理解和學習相當多的東西。升級可以說是一個可怕的過程,並且,你可能需要離線使用資料庫,執行專門的升級程式,然後在心裡默默期盼當你備份回來的時候它還能繼續工作。此外,你知道你的Postgres資料庫究竟儲存在哪裡嗎?你能隨便指一個地方,說,“那就是我的資料庫”嗎?
(眾所周知的是,有很多情況下只能使用Postgres(或MySQL,Oracle,SQL Server等)才能滿足應用程式的需求。但是我在這裡這麼說的目的,並非如此。我只是想突出說明管理SQLite 資料庫和其他典型資料庫伺服器之間的區別。)
SQLite容易管理——因為它是一個單一檔案(或在某些時候是一個檔案+事務日誌)。檔案格式在很多主要的版本上都非常穩定,所以假設我有一個從3.0.0版本(在2004年)開始的SQLite資料庫檔案,那麼我也可以使用最新的SQLite 3.10.0讀取它。如果我想將資料庫檔案放到一個U盤中,那麼我只要複製檔案,或者更好的做法是將檔案儲存在dropbox資料夾中。如果我想每天晚上備份,那麼我只要同步資料庫檔案到S3。如果我想分享一些和同事一起做的資料分析,那麼完全可以傳送一份資料庫檔案的副本給他們,然後他們就可以使用了。資料庫以一種單個檔案的形式存在,且具備穩定的格式,是SQLite的特色。
更重要的是,SQLite很容易配置。SQLite的功能可以通過兩種方式進行管理:編譯標誌和PRAGMA 語句(執行時配置)。沒有所謂的配置檔案,你只需要構建你想要的庫,然後在你建立資料庫連線時,配置執行時選項。
2.不斷提高又堅如磐石的穩定性
SQLite是由一些真正了不起的軟體工程師積極開發的。高品質的新功能正以一種驚人的速度被新增進來。就在最近,SQLite通過json1擴充套件增加了對JSON資料的支援。 SQLite還發布了全文檢索擴充套件的改進版本,其中包括使用BM25演算法的結果排名。
除了增加新的功能,SQLite的開發人員也正在努力使庫擁有更多的效能。在3.8.11版本中,釋出說明中包含這條小介紹:
SQLite現在的執行速度是3.8.0版本的兩倍,3.3.9版本的三倍
儘管出現了這麼多的變化和改進,但SQLite很少引入bug。 SQLite的測試套件被廣泛認為是行業中最好的測試套件之一,並且關於SQLite如何測試的頁面經常出現在HackerNews上,因為開發人員前赴後繼地發現了這篇令人印象深刻的文件。
3.可擴充套件和可控制
關於SQLite,我個人最喜歡的特點是它的可擴充套件性。由於SQLite是通過應用程式嵌入進去的,所以它執行在相同的地址空間裡,並且可以代你執行應用程式程式碼。無論是Python標準庫SQLite驅動程式——pysqlite,還是可選驅動器aspw,都可以提供定義了自定義SQL函式、聚合函式和歸類的API。 aspw更進一步,提供的API還可以用於定義虛擬表和虛擬檔案系統!
舉個實際的例子,假設你在一個表中有一個列用於儲存URL,你想要確定哪些是最常見的主機名——假設你使用的是不同的資料庫,那麼你將不得不寫一個複雜的正規表示式,結合了字串操作函式,或要提取資料到app並在程式碼中進行計算。使用SQLite,你就可以用Python語言定義一個hostname函式,然後用它來建立一個簡單的COUNT查詢:
from urlparse import urlparse def hostname(url): return urlparse(url).netloc conn = sqlite3.connect('my-database.db') conn.create_function('hostname', 1, hostname) # name, num_params, func
SELECT hostname(mytable.url), COUNT(mytable.id) AS ct FROM mytable GROUP BY hostname(mytable.url) ORDER BY ct DESC;
你還可以建立聚合函式,接受0…n的值,併產生單個的輸出值。例如計算標準偏差、通過用某種方式處理值來生成一個字串、做某種型別的分類,等等。
虛擬表,目前唯一由aspw支援,允許你在程式碼中定義一個表,然後查詢它,好像它是一個普通的SQL表,即使備份資料可能完全是動態的。例如,我寫了一個簡單的虛擬表,可以讓你查詢Redis就好像它是一個SQL表。
你也可以寫同名的函式,它是用於返回0…n行結果的函式。其中一個例子是一個正規表示式檢索函式,處理輸入和產生匹配令牌的行。我寫了一個庫,sqlite-vtfunc,它可以使得我們編寫這些型別的函式變得非常容易。
實際上,SQLite的每個方面都通過你的應用程式來操作。
4.快如閃電
SQLite非常快。由於它執行在同一臺機器上,所以在執行查詢或讀取結果時是沒有網路負擔的。又因為它執行在相同的地址空間,所以沒有線路協議、序列化,也不需要通過unix套接字進行通訊。當資源稀缺和效率是至關重要的時候,SQLite還可以執行在移動裝置上。 SQLite還支援大量的編譯標識,允許你刪除你不打算使用的功能。
SQLite的速度彌補了它最大的不足之處之一,那就是資料庫檔案鎖定寫入。令人難以置信的快速寫資料,只當有大量的併發寫提供服務時,資料庫鎖定才會成為一個問題。
5、WAL模式
SQLite的3.7.0版本中補充了一種利用預寫日誌的新日誌記錄方法。雖然其本身真不算是令人振奮的訊息,但這對web應用程式開發人員(或任何處理併發的人員)意味著讀的服務不會再阻塞寫的服務,反之亦然。換言之就是,讀和寫可以同時地發生。如果沒有WAL模式,那麼要想寫入資料庫,寫的服務則需要獨佔訪問資料庫,並且不能發生讀的服務,直到寫的服務結束。
下面是說明兩者之間區別的一個例子。假設,我們有兩個程式,一個寫,一個讀。寫的服務開啟了一個獨佔的事務(表明寫的意圖)。接下來,讀的服務開啟一個事務處理。然後讀的服務嘗試發出SELECT語句:
Journal mode = “delete” (the default):
- Writer:
BEGIN EXCLUSIVE
- Reader:
BEGIN
- Reader:
SELECT * FROM foo;
Error: database is locked
Journal mode = “wal”:
- Writer:
BEGIN EXCLUSIVE
- Reader:
BEGIN
- Reader:
SELECT * FROM foo;
Returns table contents
然而,值得一提的是,即使你不啟用WAL模式,寫的服務通常發生在毫秒間。這個時間是如此是短,以致於只有當你併發很高或寫的事務非常長時,才會注意到出現問題。
加分原因:BerkeleyDB
BerkeleyDB的SQLite整合,能夠給予應用程式開發人員所需的併發資料庫訪問甚至更好的效能,因為它不是鎖定整個資料庫,BerkeleyDB只需要鎖定的個別的頁面即可。這允許BerkeleyDB能在併發資料庫負載下更有效地規模化,提供的事務不會爭奪相同頁面的資料。 BerkeleyDB也支援多版本併發控制(MVCC),允許讀的操作繼續發生在資料頁面上,通過一個寫的事務來處理資料。
BerkeleyDB還有一個好處是提高了效率。換句話說,BerkeleyDB可使用更少的系統資源,執行較少的系統呼叫。你可以在此白皮書中和這篇簡要的技術概述中閱讀更多細節。
BerkeleyDB的SQL介面是SQLite的一個插入式替換,並且支援相同的API和功能。 BerkeleyDB提供了一些附加功能,如複製(SQLite有一個備份工具,但我認為它不如BDB的強大)、加密,當然還有BerkeleyDB本身的所有功能。
使用BerkeleyDB的一個主要缺點是,它是配置值非常敏感,而且要想獲取正確的頁面大小,快取大小以及其他設定,需要很深厚的知識造詣。另一個缺點是許可證——閱讀更多關於BerkeleyDB許可證的內容,檢視Oracle的許可頁面。
有關編譯Python SQLite驅動程式和BerkeleyDB的使用說明,請檢視這篇文章。
最後
我希望你能嘗試一下SQLite。不要聽信那些因循守舊的人說它不適於生產,或不適合在web應用中使用它的一面虛詞。
如果您想了解更多,SQLite本身就有一個很好地介紹了何時使用SQLite的文件,其中還包括了讓另一個RDBMS更好地工作的一系列情況。我也寫過一篇較短的文章《SQLite: Small. Fast. Reliable. Choose any three》,你可能會喜歡。
非常感謝各位抽出時間來閱讀,但是我更希望大家能夠發表評論,提出意見和建議!
譯文連結:http://www.codeceo.com/article/5-reasons-use-sqlite.html
英文原文:Five reasons you should use SQLite in 2016
翻譯作者:碼農網 – 小峰
[ 轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]
相關文章
- 2016年你應該學習的語言和框架框架
- 2016 年開發者應該掌握的十個 Postgres 技巧
- 你應該瞭解Nginx的7個原因Nginx
- 你應該瞭解 Nginx 的 7 個原因Nginx
- 【SQLite】SQLite的簡單使用SQLite
- 該試試 SQLite 的 5 個理由SQLite
- 玩家應該為遊戲質量之外的原因打差評嗎?遊戲
- android SQLite的使用AndroidSQLite
- 微軟推薦通用 Windows 應用開發者使用 SQLite微軟WindowsSQLite
- 不應該在沒有 sudo 的情況下執行 Docker 的原因Docker
- 程式設計師應該做開源專案的 6 個原因程式設計師
- 面試官:集合使用時應該注意哪些問題?我:應該注意該注意的問題!面試
- GRDB使用SQLite的WAL模式SQLite模式
- 你應該使用 Nginx + UWSGINginx
- 你應該解僱工作狂程式設計師的5個原因程式設計師
- 安卓應用安全指南4.5.2使用SQLite規則書安卓SQLite
- 3-5 年的 PHPer 應該具備PHP
- DB-Engines:2016年3月資料庫排名:Redis成功超越SQLite資料庫RedisSQLite
- 教你使用SQLite VacuumSQLite
- SQLite使用入門SQLite
- SQLite使用心得SQLite
- Sqlite使用說明SQLite
- 我們究竟應不應該使用框架?框架
- 應用卡的原因
- Swift之SQLite的基礎使用SwiftSQLite
- 2016年末程式設計師應該知道的基本架構思想程式設計師架構
- .gitignore的使用---vendor是否應該追蹤Git
- 開發者應該避免使用的6個Java功能Java
- 使用 Docker 容器應該避免的 10 個事情Docker
- 應用JDBC連線SQLiteJDBCSQLite
- Sqlite 介紹及應用SQLite
- SQLite INSERT OR REPLACE使用SQLite
- 使用angular5+ionic3+sqlite建立離線app應用AngularSQLiteAPP
- 如何在 SAP BTP Java 應用裡使用 SQLite 資料庫JavaSQLite資料庫
- SQLite的sqlite_sequence表SQLite
- SQLite的sqlite_master表SQLiteAST
- 應該使用什麼 CI/CD 工具?
- 學習和使用PHP應該注意的10件事PHP