您好,歡迎來(lái)電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>源碼下載>數(shù)值算法/人工智能>

使用SQLite數(shù)據(jù)的幾個(gè)原因

大?。?/span>0.17 MB 人氣: 2017-10-10 需要積分:1
SQLite 是非常優(yōu)秀的數(shù)據(jù)庫(kù),能夠在真實(shí)的生產(chǎn)環(huán)境中完成一些真正的工作。本文將列出五個(gè)我認(rèn)為在2016年應(yīng)當(dāng)選用 SQLite 的原因。
  
  便于管理
  不知你是否管理過(guò) Postgres 數(shù)據(jù)庫(kù)?想要確保數(shù)據(jù)庫(kù)服務(wù)器正確配置,需要了解不少東西,比如共享緩存、有效緩存大小、work mem、work mem 的維護(hù)以及 wal 緩存等等。此外升級(jí)的過(guò)程也很恐怖,使用者需要先將數(shù)據(jù)庫(kù)離線,運(yùn)行程序來(lái)升級(jí),然后祈禱在重新打開(kāi)時(shí)能正常運(yùn)作。另外,postgres 數(shù)據(jù)庫(kù)具體在哪里呢?你能否指著某個(gè)地方說(shuō):“那就是我的數(shù)據(jù)庫(kù)?”
  雖然我們都知道,在很多情況下只有 Postgres(或 MySQL、Oracle、SQL Server 等)對(duì)應(yīng)用的某些需求很有效果,不過(guò)這不是本文的討論范圍,本文只想強(qiáng)調(diào)管理 SQLite 數(shù)據(jù)庫(kù)與傳統(tǒng)數(shù)據(jù)庫(kù)服務(wù)器之間的區(qū)別。
  SQLite 便于管理——只有單個(gè)文件(有時(shí)候是一個(gè)文件+事務(wù)日志),這個(gè)文件的格式在多個(gè)主要版本中都是通用的,也就是說(shuō)如果我有一個(gè)3.0.0版本(2004年)的 SQLite 數(shù)據(jù)庫(kù)文件,便可以在最新的 SQLite 3.10.0上使用。如果想要在別處使用這個(gè)數(shù)據(jù)庫(kù)文件,也只需復(fù)制到U盤(pán)里,甚至存放到云存儲(chǔ)中。如果想要每天晚上進(jìn)行備份,只需將此數(shù)據(jù)庫(kù)文件同步到 S3。如果想要與同事分享我的數(shù)據(jù)分析,也只需給他們發(fā)送一份數(shù)據(jù)庫(kù)文件備份即可。這個(gè)數(shù)據(jù)庫(kù)的一大特性就是只有單文件,且文件格式多年以來(lái)非常穩(wěn)定。
  此外,SQLite 配置起來(lái)也很簡(jiǎn)單,其功能有兩種管理方式:編譯標(biāo)識(shí)以及編譯指示語(yǔ)句(運(yùn)行時(shí)配置)。沒(méi)有什么配置文件,只需使用想要的功能來(lái)構(gòu)建相應(yīng)的庫(kù),然后在建立數(shù)據(jù)庫(kù)連接時(shí)配置運(yùn)行時(shí)選項(xiàng)即可。
  穩(wěn)定性堅(jiān)如磐石,且還在不斷提高
  目前有一些優(yōu)秀的大牛工程師正在積極地進(jìn)行 SQLite 的開(kāi)發(fā),使得 SQLite 新增高質(zhì)量新功能的速度十分驚人。就在最近,SQLite 還加入了 json1 擴(kuò)展程序以支持 JSON 數(shù)據(jù),想要了解如何在 Python 中使用它,請(qǐng)查看這篇文章。SQLite 還發(fā)布了一個(gè)全文搜索擴(kuò)展包的改進(jìn)版,其中包括使用 BM25 算法對(duì)結(jié)果進(jìn)行排序。
  除了新增功能之外,SQLite 的開(kāi)發(fā)者也在努力改進(jìn) library 的性能,在3.8.11版本的發(fā)布說(shuō)明中,包含這些宣傳內(nèi)容:
  新版本 SQLite,運(yùn)行速度是3.8.0版本的兩倍,是3.3.9版本的三倍。
  盡管一直在更新和改進(jìn),SQLite 卻很少有新增的 bug。SQLite 的測(cè)試套件公認(rèn)是業(yè)內(nèi)最好的測(cè)試套件之一,而“ SQLite 是如何測(cè)試的”相關(guān)文檔也被頻繁推薦到 HackerNews 上。
  可擴(kuò)展性與可控性
  筆者最喜愛(ài) SQLite 的地方是它的可擴(kuò)展性,SQLite 是應(yīng)用嵌入式的,它與應(yīng)用運(yùn)行在同一個(gè)地址空間中,并能代表你執(zhí)行應(yīng)用代碼。在 Python 標(biāo)準(zhǔn)庫(kù)中,無(wú)論是 SQLite 驅(qū)動(dòng)的 pysqlite ,還是可選驅(qū)動(dòng) apsw 都為自定義 SQL 函數(shù)、聚合函數(shù)與排序規(guī)則提供了相應(yīng)的 API;apsw 更進(jìn)一步,為定義虛擬表和虛擬文件系統(tǒng)提供了相應(yīng)的 API。
  在實(shí)際案例中,假設(shè)表格中有一列用于存儲(chǔ) URL,你還想確定最常見(jiàn)的主機(jī)名是哪些——如果使用不同的數(shù)據(jù)庫(kù),就必須編寫(xiě)復(fù)雜的正則表達(dá)式(字符串操作函數(shù)組),或者將數(shù)據(jù)從應(yīng)用中抽出來(lái),然后在代碼中進(jìn)行計(jì)算。使用 SQLite 的話,就可以在 Python 中定義主機(jī)名,并使用它來(lái)創(chuàng)建簡(jiǎn)單的 COUNT 查詢:
  fromurlparse importurlparse defhostname(url):returnurlparse(url).netloc conn = sqlite3.connect(‘my-database.db’) conn.create_function(‘hostname’, 1, hostname) # name, num_params, func
  SELECThostname(mytable.url), COUNT(mytable.id) ASct FROMmytable GROUPBYhostname(mytable.url) ORDERBYct DESC;
  還可以創(chuàng)建聚合函數(shù),輸入0……n的值,生成單獨(dú)的輸出值。樣例可能包括:計(jì)算標(biāo)準(zhǔn)差、通過(guò)處理值來(lái)生成字符串、進(jìn)行某種類型的分類等。
  虛擬表目前僅受 apsw 支持,用戶可以在代碼中定義表格,并將其當(dāng)作普通的 SQL 表格查詢,即便后臺(tái)數(shù)據(jù)是完全動(dòng)態(tài)的。比如,我編寫(xiě)了一個(gè)簡(jiǎn)單的虛擬表格,允許用戶將其當(dāng)作 SQL 表格來(lái)查詢 Redis。
  你也可以編寫(xiě)同名函數(shù),返回0……n行結(jié)果,比如正則表達(dá)式:處理輸出內(nèi)容,并生成一行行匹配 token。我寫(xiě)了一個(gè)庫(kù)叫做 sqlite-vtfunc,用來(lái)編寫(xiě)這類函數(shù)非常簡(jiǎn)單。
  實(shí)際上,SQLite 的各個(gè)方面都可以受應(yīng)用的控制。
  快如閃電
  SQLite 速度非???,它運(yùn)行在同一臺(tái)機(jī)器上,因此在執(zhí)行查詢或讀取結(jié)果時(shí)并不產(chǎn)生網(wǎng)絡(luò)開(kāi)銷。由于與應(yīng)用運(yùn)行在同一個(gè)地址空間中,因此并無(wú)連接協(xié)議、序列或通過(guò) unix socket 通訊的需求。SQLite 也可以在資源匱乏、要求高效率的移動(dòng)設(shè)備上運(yùn)行,并支持大量的編譯標(biāo)記:允許用戶移除沒(méi)有計(jì)劃使用的功能。
  SQLite 的速度彌補(bǔ)了它的最大缺點(diǎn)之一:寫(xiě)入時(shí)數(shù)據(jù)庫(kù)文件鎖定。通過(guò)快速寫(xiě)入數(shù)據(jù),只有當(dāng)有大量的并發(fā)寫(xiě)入時(shí),數(shù)據(jù)庫(kù)鎖定才會(huì)成為問(wèn)題。
  WAL模式
  SQLite 的3.7.0發(fā)布版增加了新的日志記錄方法:使用預(yù)寫(xiě)日志。單獨(dú)來(lái)看這個(gè)消息并不太吸引人,但對(duì)于 web 應(yīng)用開(kāi)發(fā)者來(lái)說(shuō)(或者要應(yīng)付并發(fā)問(wèn)題的開(kāi)發(fā)者來(lái)說(shuō)),這意味著讀取并不會(huì)再阻礙寫(xiě)入了,反之亦然?;蛘邠Q句話說(shuō),讀取和寫(xiě)入能夠并發(fā)進(jìn)行。沒(méi)有 WAL 模式的話,想要寫(xiě)入數(shù)據(jù)庫(kù)則要求寫(xiě)入程序獨(dú)占數(shù)據(jù)庫(kù)的訪問(wèn)權(quán),在寫(xiě)入完成前無(wú)法讀取。
  下面是一個(gè)樣例,說(shuō)明了兩者的不同。假設(shè)我們有兩個(gè)進(jìn)程,一個(gè)寫(xiě)入、一個(gè)讀取。寫(xiě)入程序開(kāi)啟了獨(dú)占事務(wù)(表明打算寫(xiě)入);讀取程序開(kāi)啟事務(wù);讀取程序嘗試發(fā)布SELECT語(yǔ)句:
  Journal mode = “delete”(the default): Writer: BEGIN EXCLUSIVE Reader: BEGIN Reader: SELECT* FROMfoo; Error: database islocked
  Journal mode = “wal”: Writer: BEGINEXCLUSIVE Reader: BEGINReader: SELECT* FROMfoo;Returns table contents
  然而值得注意的是:即使不啟用 WAL 模式,寫(xiě)入通常在幾毫秒中發(fā)生。這個(gè)時(shí)間太短了,用戶只會(huì)在并發(fā)很高或者寫(xiě)入事務(wù)用時(shí)很長(zhǎng)時(shí)才會(huì)注意到這個(gè)問(wèn)題。
  額外的原因:BerkeleyDB
  由于只需鎖定單獨(dú)頁(yè)面,而無(wú)需鎖定整個(gè)數(shù)據(jù)庫(kù),集成了 SQLite 的 BerkeleyDB 可以給需求數(shù)據(jù)庫(kù)并發(fā)訪問(wèn)的應(yīng)用開(kāi)發(fā)者有更好的體驗(yàn)。而且這樣一來(lái),BerkeleyDB 在并發(fā)數(shù)據(jù)庫(kù)負(fù)載的情況下也能更高效地?cái)U(kuò)展,使得各事務(wù)無(wú)需爭(zhēng)奪同一個(gè)頁(yè)面內(nèi)的數(shù)據(jù)。
  BerkeleyDB 還支持多版本并發(fā)控制(MVCC),使得讀取操作也可以繼續(xù)在寫(xiě)入操作的同一個(gè)頁(yè)面進(jìn)行。
  另外,BerkeleyDB 還有一個(gè)優(yōu)勢(shì)就是效率更高。換句話說(shuō),它使用的系統(tǒng)資源與調(diào)用系統(tǒng)都更少,可以參考這份白皮書(shū)及這個(gè)簡(jiǎn)明技術(shù)概覽找到更多細(xì)節(jié)。
  BerkeleyDB 的 SQL 接口是作為 SQLite 的簡(jiǎn)易替代,所支持的API與功能是相同的。BerkeleyDB 還提供了一些額外的功能,比如復(fù)制(SQLite 有備份程序,但在我看來(lái)效果不如 BDB 的強(qiáng)大)、加密,當(dāng)然還有 BerkeleyDB 自身的所有功能。
  使用 BerkeleyDB 主要的缺點(diǎn)在于:它對(duì)配置數(shù)值非常敏感,而了解正確的頁(yè)面大小、緩存大小以及其他設(shè)置參數(shù)需要對(duì)相關(guān)知識(shí)有較深的了解。另一個(gè)缺點(diǎn)是證書(shū)問(wèn)題:關(guān)于 BerkeleyDB 的證書(shū)問(wèn)題請(qǐng)參考 Oracle 的證書(shū)頁(yè)面。
  想要查看如何編譯 Python SQLite 驅(qū)動(dòng)以使用 BerkeleyDB,請(qǐng)查看這篇文章。
  總結(jié)
  我希望你們嘗試一下 SQLite,別相信守舊者的說(shuō)法:什么不適用于生產(chǎn)環(huán)境,或者不適合用在 web 應(yīng)用中。
?

非常好我支持^.^

(0) 0%

不好我反對(duì)

(0) 0%

使用SQLite數(shù)據(jù)的幾個(gè)原因下載

相關(guān)電子資料下載

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?