转载http://www.cnblogs.com/eyesworld/p/3311286.html
SQLite概述
关于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实际产品应用过程中的优缺点做了分析,对其一些开源、商业应用做了简单介绍,并写下了一些个人的考虑,希望能和大家做更深入的交流。