關於SQLite數據庫的特性,相信網上已經有很多,我這里根據親身經驗,做個不完全總結,先總結優點:
- 零配置,最簡可簡化到一對.c,.h代碼,在各個平台上都很輕易編譯通過,非常感激作者
- 任何時候都可以免費使用,沒有任何的依賴,只希望“May you do good and not evil. ”——願你做好事,不要做壞事。SQLite產品瞬間變的非常偉大起來
- 以單文件方式存儲,文件可在任何平台上傳輸和使用,管理維護非常方便
- 實現了SQL92標准的絕大部分標准,做統計、分析等很多操作都有完備的語法和函數
- 多記錄數據插入/更新一定要使用事務,使用和不使用事務,其時間差距是巨大的(這個只能稱作特點)
- SQLite的數據存儲安全性是非常好的,基本不存在數據丟失的情況,提供了幾種不同級別的應急處理選項(例如設備斷電)
- SQLite的接口非常開放,很多的處理函數都可以自己編寫並注冊進去,替換現有功能。比如,SQLite做數據加密也很容易,寫加解密函數注冊進去
- SQLite支持自定義函數注冊,這個是實現空間數據庫OGC查詢規范的重要技術支撐,當然MySQL、Oracle也可以這么做
- SQLite支持R樹索引,這個也是存儲空間數據庫的核心 ,經過我長期驗證,其更新性能和檢索性能都很優異,我自己嘗試寫於基於普通表的網格索引,性能差的遠了,也可能是我的實現有問題。但R樹索引也有缺點,后面會談到。
- 有很多的開源工具可以使用,我很多小伙伴都在用它
- 支持全文檢索的表模式,這個我是下一步准確研究和使用的,我考慮使用它來處理一些非結構化數據的存儲,會用到全文檢索的技術。
- 總之,優點挖掘不盡啊。。。
再總結缺點:
- SQLite對SQL語法的支持不完整,例如刪除字段操作,右連接操作,都是不可實現的,低版本的復雜Union操作,是有問題的
- SQLite的R樹是有缺點的,R樹可以選擇基於INT還是FLOAT存儲,但不管選擇哪個,都是4個字節,存儲經緯度或者平面數據會有10米級別的損失,在做精確查詢的時候,可能會查不出對象,例如用點位對查該位置的點。我們也花了很大的功夫改造了SQLite源碼解決了這個問題,使存儲8個字節,數據量會增大。
- SQLite支持指定的內存塊作為緩存,也可控制緩存大小,這個本應該是個很大的優點。做過WinCE的人了解,WinCE上的每個應用程序只能占用32M內存,但我的應用程序遠遠需要比這個大,所以我開辟了文件映射緩存(WinCE上可以這樣繞過去開辟大內存),然后將內存交給SQLite管理,實驗也是成功的,但穩定性是恐怖的,我翻爛了相關的屈指可數的幾篇文章,也沒解決穩定性問題,我和小伙伴們辛苦的研究了近一個月,以我瘦了將近10斤的代價和回歸技術的原點收場,真的很難忘。后來,不得不從程序的角度縮減內存。
- 對了,還是解釋一下背景,我做的是移動GIS的系統,存儲50萬級別的地理圖形,每個圖約100個節點(double x,y),合計約5千萬個double xy, 通過配置好地圖,進行快速的瀏覽、查詢、顯示,當時顯示速度也能控制在2秒以內,也可以做圖形的采集,編輯,效果還是可以的。
寫上面的優點,我幾乎一氣呵成,寫缺點的時候,我還是想了又想的,一是回憶了痛苦的過程,二是缺點確實不多,我也常在想,如果世界上沒有SQLite這個東西,我所做的事,會有多么我現在不一樣。因為如果沒有它,我至今也沒發現能替代它的數據庫。那么,我就需要設計一種自己的數據格式,來處理移動平台的海量數據存儲和管理技術,這真的不是我現在的技術專長。
感想有很多,先這么簡單的總結一下,如果有使用到以上特性的SQLite的朋友,希望也能看下我所遇到的問題,避免碰到釘子。
因為R樹對空間存儲比較重要,再簡單解釋一下R樹概念,給不了解空間索引的朋友。(當然還有四叉樹索引、網絡索引等索引模型,大家可以再去了解。)
R樹是GUTTMAN於1984年提出的最早支持擴展對象存取方法之一,也是目前應用最為廣泛的一種空間索引結構。許多商用空間數據庫系統,如MapInfo SpatialWaro和Oracle Spatial等均提供對R樹的支持,開放源碼系統PostgreSQL也實現了R樹。近二十多年來,許多學者致力於R樹的研究,在R樹的基礎上衍生出了許多變種。比較典型的有R+樹、R·樹、壓縮R樹等。
R樹的數據結構
如上所述,R樹是B樹在高維空間的擴展,是一棵平衡樹。每個R樹的葉子結點包含了多個指向不同數據的指針,這些數據可以是存放在硬盤中的,也可以是存在內存中。根據R樹的這種數據結構,當我們需要進行一個高維空間查詢時,我們只需要遍歷少數幾個葉子結點所包含的指針,查看這些指針指向的數據是否滿足要求即可。這種方式使我們不必遍歷所有數據即可獲得答案,效率顯著提高。下圖1是R樹的一個簡單實例:

網上也檢索了一篇文章,供大家進一步的學習:《R樹空間索引》http://blog.csdn.net/zhouxuguang236/article/details/7898272
矢量數據存儲格式Spatialite
這是它的Logo,前面講過,它也是帶根羽毛的,表示一種輕快的感覺。其基本原理是通過擴展SQLite對SQL語句的支持,使其能夠支持OGC定義的空間數據查詢規范,例如Intersect,Union,AsText這樣一系列的函數,基本實現了一個完整的空間數據庫存儲系統,而且繼承了單文件,便於分發的優點。
但它的缺點也是顯而易見的,我總結如下:
- 編譯的復雜性:Spatialite已經不再是單一自包含的庫,GEOS/PROJ/libiconv等等,網上經常看到有朋友痛苦的在安卓上編譯。我一直認為跨平台編譯,是個高技術活
- 引用的開源庫的不穩定性:Spatialite具有不穩定性,產品有時候會因此被動升級,例如GEOS的BUG,還是有一些的,為了解決問題,不得不經常跟隨升級,這樣也涉及到Spatialite升級帶來的數據版本不一致的問題(即數據文件的格式升級),比如高版本Spatialite寫不了低版本的Spatialite數據庫。我了解Spatialite目前是沒提供這個平滑升級機制的
- 改造的復雜性和不可控:國內行業常常有數據保密安全需求,這樣就需要我們對數據格式做加密,就要改造Spatialite,這個改造牽扯的一些關聯庫變更,會有不可控性。Spatialite存儲的WKB並不是真正的WKB,格式上是有區別的,這些方面,也都要考慮。
所以,我覺得在能力所能及的情況下,還是自己實現基於SQLite的空間數據庫比較好,不過要提一下,完整實現OGC的空間數據查詢規范,絕不是易事,實現那個GEOS的替代品,也絕不是易事。但是,重點還是要看需求,如果應用需求不是非常復雜,那么實現數據庫的簡單矩形檢索,再實現幾何圖形的一些簡單訪問操作,可能也就夠用了,這樣自己是可控的。另外,如果在面臨以上我分析的幾個問題,仍然具備Spatialite的高超駕馭能力,何不自己去實現呢。
影像數據存儲格式Rasterlite
和Spatialite同源的開源產品,我研究的非常少,其核心原因是分級瓦片是存儲,這樣一說大家也非常明白了。谷歌、百度地圖啥的,都是這樣的原理。
MBTile
另外一個國外開源影像存儲設計叫MBTile,也是基於SQLite,給出了詳細的表結構,和分級瓦片的計算方法,沒什么本質區別。
我只是有一些了解,SQLite在GIS行業內用的還是比較普遍的,國外ArcGIS也在用。(其實我覺得ArcGIS真有必要做一個基於文件SQLite存儲的Personal GDB,來代碼它那個基於MDB的笨拙的Personal Geodatabase,或者它覺得FileGDB已經達到相同的目標了?但FileGDB畢竟不太具備SQL92級別的純關系數據庫訪問能力)
另外,國內吉奧的也用SQLite來存儲文件式分級瓦片數據,效果也還是很不錯的。
但對於影像的存儲,我還是有一些個人的想法:
- 有能力的話,還是做自己的文件式瓦片數據存儲,因為瓦片數據格式非常規范,基本不用考慮數據變更(或從更上層次考慮)。做索引也很容易,性能也很容易超越SQLite,至於數據量用文件存儲更不是問題。
- 做影像(遙感、航片)類的瓦片,建議大家都采用混合模式(ArcGIS叫MIX模式),對於無透明區域的瓦片,采用JPG高壓縮,對於有透明區域的瓦片,采用PNG方式,這樣得到的影像存儲是最小的,傳輸性能是最好的,甚至能得到原來體積1/10的壓縮結果。我原先一直以為PNG是最輕最小的,現在才知道自己知之甚少,對圖片格式研究太少了。
本文主要對SQLite實際產品應用過程中的優缺點做了分析,對其一些開源、商業應用做了簡單介紹,並寫下了一些個人的考慮,希望能和大家做更深入的交流。


