sqlite 内存数据库库,MySQL和sqlite,哪个更好

当前位置: >
> 浅谈SQLite:实现与使用浅谈SQLite:实现与使用更新:&&&&编辑:丹冬&&&&来源:用户投稿&&&&人气:加载中...&&&&字号:|标签:&&&&&&&&
  有一些日子没有仔细关注SQLite了,今天打开其,发现其的版本已经是3.6.22了,更让我惊喜的是它的用户越来越多,而且邮件列表的关注者也越来越多,突然认为自己已经太old了。惊喜的同时,不得不聊上几句了。
  首先,来看看都有哪些人在SQLite,上列举一长串NB的用户,其中不乏像Adobe,Apple,Firefox,甚至连google,Microsoft,SUN这样的用户。
  Firefox:这是我的机器上V3.5.7安装下的文件:
  可以发现用的SQLite 3.6.16.1。
  据说,Google在它的Desktop for Mac,Google Gears,以及Android,甚至Chrome中都用到SQLite,而且,Google的工程师对SQLite的全文检索功能作了很大的贡献 (contribution)。还有Apple,Micorsoft,SUN等等,这里就不列举了。详细见。有这些的参与,对SQLite的发展应该有很大的,尤其是像Google这样的用户。
  2、与使用
  下面从及使用的角度来谈谈SQLite,先看看SQLite的特性(功能)吧。
  简单(simple):SQLite是一个非常轻量级自包孕(lightweight and self-contained)的DBMS:一个头文件,一个动态库文件,你就拥有了关系数据库的所有功能了。简单,是SQLite最明显的哲学。它供给的API少而简单。只需要一个DLL文件,你的马上就拥有了一个功能强大的数据库引擎,这是一件很美妙的事。
  小巧(small):我用VS 2005在Windows下编译的3.6.11,Release版为368K,用时不到20秒――而编译MySQL时,要花上几分钟。而当我插入10000条int数据时,内存开销660K,磁盘开销92K。
  事务(transaction):事务是现代商业数据处理系统最基本的要求,而Access,不论是在可履行文件大小(看了一下Access2003的可履行文件大小为6.32M,两者不是一个量级),还是事务特征,都是不能和SQLite 相比的。
  并发性(Concurrency):由于SQLite通过OS的文件锁来实现库级锁,粒度很大,但是,它通过一些繁杂特殊的处理(具体可以参见分析系列),尽量的提升了读写的并发度。如果你还有担心,你可以看看这篇:。
  SQL92:SQLite支持绝大部分的标准SQL语句,你只需要几百K的,就可以换来需要上百兆的通用DBMS几乎所有操作了。
  方便(Convenience):如果你的要SQLite,只需要将拷贝你的程序即可。
  开源(Opensource):这是它最强大的地方。开源,意味着你可以品读它的,你可以随时改动它,加入你自己的特征,而这一切完全的。开源,是一种精神。
  实现部分
  好了,现在从实现的角度来谈谈个人体会,这也是我对比关注的。
  SQLite是一款优秀的嵌入式数据库管理系统,这里有两层含义:一是它经常作为动态库嵌入到使用程序;另外一方面它通常用于嵌入式设备或其它要求较低的桌面使用。如果把它作为内存数据库,个人认为不是很适合。终究,它的写并发性不是很好,此时, TimesTen也许会更好,Berkey DB也许是一个不错的选择。SQLite这样的嵌入式数据库与主存数据库的使用处景、实现以及对的需求都是不一样的。
  (1)事务处理
  事务的核心有两个:并发把持和恢复。了并发把持和恢复的系统,就能允许它的用户假设程序是原子的(atomically)履行的――好像没有其它的程序同时履行;而且是可靠的(reliably)――不会产生失败。原子性和可靠性的抽象,则称为事务(transaction)。其实,事务并不是DBMS的专利,任何分布式系统,都面对并发和恢复问题,而的法子就是事务,只不过,我们更常听到DBMS中的事务。
  并发把持保证事务的原子履行,它使得交错履行的事务看起来是一个接一个的顺序履行的,完全没有交错履行。如果交错履行的结果与顺序履行的结果一致,则称为串行化(serializable)。
  恢复使得数据库仅仅包孕那些正常完成的事务的结果。如果事务在履行的历程中发生差错,不能持续进行,恢复算法必须清除部分完成事务产生的影响。
  并发把持
  SQLite只支持库级锁,库级锁意味着什么?――意味着同时只能允许一个写操作,也就是说,即事务T1在A表插入一条数据,事务T2在B表中插入一条数据,这两个操作不能同时进行,即使你的机器有100个CPU,也无法同时进行,而只能顺序进行。表级都不能并行,更别说元组级了――这就是库级锁。但是,SQLite尽量延迟申请X锁,直到数据块真正写盘时才申请X锁,这是非常巧妙而有效的。
  SQLite的恢复技巧是影子分页技巧(shadow paging)技巧的典型代表。
  DBMS的常用恢复技巧有影子分页技巧与基于日志的技巧,前者在早其数据库管理系统中用到,比如System R,现代DBMS中已经很难见到它的身影了。
  影子分页技巧与基于日志技巧相比,优点是实现简单,消除了写日志记载的开销,恢复的速度也快(不需要redo和undo)。影子分页的缺点就是事务提交时要输出多个块,这使得提交的开销很大,而且以块为单位,很难使用到允许多个事务并发履行的情况――这是它致命的缺点。
  (2)查询处理
  SQLite的查询处理本色上就是一个SQL编译器和一个虚拟机。而实现这些功能只用了十多个文件,全部实现实现简单而有效,但是也存在一些问题。首先,SQLite字典数据很简单,实际上它的字典就一个表sqlite_mater,所有的信息都是通过对sqlite_master中SQL语句进行解析获取的,而解析一个SQL语句,都需要进行词法分析、语法分析、甚至虚拟机代码的生成。而这一历程是很需要光阴的,而且,查询企图也没有重用。其次,查询优化还对比简单,特别是连接操作,只通过循环来做(MySQL也一样)。但是,仅仅数万代码,我们不能对它要求太苛求。
  (3)模型
  SQLite的文件物理上被划分成相同大小的块;逻辑上划分成一些B-Tree――每个表对应一个B-Tree。而没有像Oracle,或者 InnoDB对数据块进行繁杂的逻辑组织,这种按需分配数据块的做法必定影响磁盘的读写性能。不过,归根到底,还是源于它的使用处景。
  (4)缓冲区管理
  Buffer的管理对于DBMS,无疑是非常首要的,SQLite在其它方面做得对比简单,但是在缓冲区管理这一块,它还是做足了功夫。 SQLite采纳DBMS常用的LRU算法。更值得一提的是,在较新的版本中,SQLite采纳和虚拟文件系统的类似的方式,实现了让默认缓冲区管理子系统可以很容易的切换成其它的缓冲区管理算法,这是非常灵便的。
  (5)I/O
  SQLite采纳简单的阻塞I/O,较新的版本将异步I/O作为可选的扩展,但是,由于SQLite没有日志,所以,事务中ACID中的D,就无法保证,所以,如果你的数据很关键,请不要用SQLite的异步I/O。另一方面,实际上,很多嵌入式操作系统,比如Windows CE并不支持异步I/O(不过,这可以通过多线程加以解决)。
  但是,这些“缺点”并不是SQLite的缺点,相对于通过DBMS,恰恰是它的优点,这样的实现简单,而且对的需求较低。对嵌入式设备、或者那些要求较低的使用,已经足够,足够就好。
  使用处景
  嵌入式设备:这应该是SQLite使用的主要场景,很多都在他们的嵌入式使用程序中SQLite,其中不乏google的Android。
  桌面使用:如果你已经厌恶了fopen,fread,fwrite这些函数,SQLite是你不错的选择,,它接口简单,而且支持事务。前些天无意中下了一个cookie清除――CookieCrumbler,打开一看,发现里面竟然有一个sqlite3.dll,着实让我震惊了一把。
  Websites:如果你的站点的造访量、数据量小的个人站点,SQLite可以代替开销较大的MySQL和复杂的Access。
评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
分类选择您可能在找这些帮设计师节省1,085,543,232小时几种常用的开源内存数据库性能比较 - 开源中国社区
当前访客身份:游客 [
当前位置:
要做一个网络内存数据库,在处理结点准备采用开源内存数据库修改完成。
比较常用的有FastDB、SQLite、Berkeley DB、GigaBASE等。
但不知道他们的性能如何,请各位大侠指点一二。
有更好的也可以推荐。
共有4个答案
<span class="a_vote_num" id="a_vote_num_
BDB并不是内存数据库啊?
--- 共有 1 条评论 ---
BDB可以配置成内存数据库
(3年前)&nbsp&
<span class="a_vote_num" id="a_vote_num_
H2 Database不知道怎么样啊?
<span class="a_vote_num" id="a_vote_num_
更多开发者职位上
有什么技术问题吗?
类似的话题笔试题/面试题(286)
MySQL/Oracle/SQL Server(41)
原文地址:http://blog.csdn.net/nanfeiyannan/article/details/9003009
开源或商业
不开源,商业使用付费
1. 符合RDBMS标准的独立内存数据库服务。
2.支持SQL访问,支持ODBC&JDBC。
3.本身不支持与非Oracle数据库的互操作。
4.高可靠性,支持完整日志,支持镜像复制功能。
5.目前不支持存储过程和触发器。
6.内存结构简单,并没有数据库缓冲区、保存池或丢弃池的概念。
7.目前支持散列索引和T树索引,前者仅支持余键-&#20540;查找,速度非常快,执行过程与底层表的数量无关,具有较高的读取扩展性和很好的并发性;T树索引读取效率很高,但是,在繁重写操作时,并发性较差。
不开源、商业使用付费
1.被整合到Sysbase ASE平台中(TimesTen则为一个独立的数据库)。
2. 基于经典ASE数据库模板创建。
3. 采用复制技术实现读取其他数据源的数据。
4. 完全支持ASE本身的SQL语法、安全性和加密。
IBM SolidDB
不开源、商业使用付费
1.可以提供超快的速度和超高的可用性,可以提供每秒数万至数十万事务的吞吐率,并且始终可以获得微秒级的响应时间。
2.抛弃块结构,表行和索引节点独立地存储在内存中,可以直接添加索引,而不必重新组织大块结构。
3.放弃使用大块索引,以精简结构、增加索引层数、将索引节点最小化,从而避免节点内处理的成本。
4.使用一种称作trie(前缀树)的索引方式,更适合现代处理器缓存,通过有效促进缓存的使用来提高处理器的效率,从而实现性能的最大化。
5.使用一种获得专利的检查点方法来加快数据处理,查询事务的延时通常是10到20微秒,更新事务的延时通常小于100微秒。
开源版本免费
商业版本需付费
1.基于存储过程的事务提交方式:用户通过写存储过程完成应用程序的逻辑,作为一个先置条件将存储过程提交到VoltDB,运行时,用户程序调用存储过程完成事务操作,所有事务的运行逻辑是由VoltDB在服务器进程中完成。
2.基于Shared Nothing结构的数据分布,整个数据库的数据分散到集群的多台机器上。
3.基于哈希的数据分布策略,好处是数据分散的均匀,没有动态数据调整的烦恼;缺点是新增的机器需要停止服务后重新分布数据。哈希方法打乱了数据的连续性,使得VoltDB对于范围查询的处理能力显著下降。
4.其事务并发控制需要依赖于集群内所有机器的时间一致,其数据分片规模是按照集群核数来划分,当整个系统压力比较大时,可以使事务的时延有效降低。
不开源的商业数据库,
测试版本在功能上与正式版没有区别,但是,对连接次数做了限制
1.高性能和高效的存储效率,为了提高性能方便程序使用,eXtremeDB中的数据未做任何压缩。
2.不仅开源建立完全运行在主内存的内存数据库,更可以建立磁盘/内存混合介质的数据库。
3.嵌入式数据库:其内核以链接库的形式包含在应用程序之中,开销只有50KB-130KB;避免了进程间的通信,从而剔除了进程间通信的开销和不确定性;其独特的数据&#26684;式方便程序直接使用,剔除了数据复制及数据翻译的开销,缩短了应用程序的代码执行路径。
4.由应用定制的API,应用程序对eXtremeDB数据库的操作接口是根据应用数据库设计而自动产生,剔除了通用接口所必不可少的动态内存分配。
5.其独特的体系结构,保证了数据管理的可预测性。
开源,免费使用
商业目的的分发版免费
1.需要专业支持则需要购买。
2. 在并发(包括多进程和多线程)读写方面的性能一直不太理想。数据库可能会被写操作独占,从而导致其它读写操作阻塞或出错。
3.32\64位主流均支持。
4.不支持ODBC连接,需通过第三方驱动支持JDBC连接。
开源,免费使用
商业目的的分发版免费
1.需要专业支持则需要购买。
2. 并发性较好(在模拟器中有使用,支持50个并发查询没问题),数据量少的情况,查询速度很好。
3.32\64位主流操作系统均支持,但需平台支持。
4.支持ODBC&JDBC
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:76336次
积分:3787
积分:3787
排名:第6587名
原创:163篇
转载:455篇
译文:77篇
评论:10条Sqlite内存数据库在多线程下的使用问题
Sqlite内存数据库在多线程下的使用问题
我已经往内存数据库A插入了10W条数据,我现在想把A导入一个物理文件B(具有相同表结构),是不是应该用attach指令?有没有高人详细指点一下?sqlite3_open(":memory:", &db);...ret = sqlite3_exec(db, "CREATE TABLE new_table1 (id integer primary key autoincrement,name vchar(32))", 0, 0, &zErrMsg);ret = sqlite3_exec(db,"begin transaction",0,0,&zErrMsg);ret = sqlite3_exec(db, "insert into new_table1 (name) values ('123');", 0, 0,&zErrMsg);ret = sqlite3_exec(db,"commit transaction",0,0,&zErrMsg);到上面,数据库已经插入内存数据库了,然后再怎么导入物理文件B?sqlite3_open("c:/A.dat", &db);ret = sqlite3_exec(db,"attach A.dat as new_db2",0,0,&zErrMsg);ret = sqlite3_exec (db,"insert into new_db2.new_table2 (name) values('name')",0,0,&zErrMsg);ret = sqlite3_exec(db,"detach new_db2",0,0,&zErrMsg);if (ret!=SQLITE_OK)MessageBox("附加数据库失败!");这样会提示"附加数据库失败!",不知道是那里写错了...&&&搞反了,应该把文件数据库attach到内存数据库中。sqlite3_open("c:/A.dat", &db);这一句是多余的,应该去掉。ret = sqlite3_exec(db,"attach 'c:/A.dat' as new_db2",0,0,&zErrMsg);这样就可以从内存数据库中复制数据到文件数据库中了,文件数据库中没有表时使用(注意新表没有索引):create table new_db2.new_table1 as select * from new_table1;有表时使用:insert into new_db2.new_table1 select * from new_table1;&已经搞定~ret = sqlite3_exec(db,"attach 'c:/A.dat' as new_db",0,0,&zErrMsg);ret = sqlite3_exec(db,"begin transaction",0,0,&zErrMsg);ret = sqlite3_exec(db,"insert into new_db.new_table2 (name) select name from new_table1",0,0,&zErrMsg);ret = sqlite3_exec(db,"commit transaction",0,0,&zErrMsg);300万条内存数据,10个字段,大概写入了631MB物理文件&&&并没有多线程写操作,A线程是不停读,B线程是某一时候去写/修改!A先启动,过段时间B才启动,但是由于A线程是每20毫秒随机从50万条数据中读一条数据,所以查询间隔很快(20ms);此时B线程写1万条数据,然后随机修改2万条数据,B始终是成功的,但是在B操作的同时,A几乎时候处于busy状态,大部分查询(20ms)都是返回busy状态,偶尔能查询出一个值(估计是在B线程写/修改某条数据成功,还未开始下条数据的写/修改的空隙时),B线程写/修改一完成,A线程马上就正常了。得到三点结论:1、任何数据库都有读/写互斥(锁),oracle/sqlserver/mysql/sqlite...2、完全可以修改sqlite源代码,在thread读写有互斥的时候适当的sleep或者提示(新版的sqlite lib已经增加了sqlite3_busy_timeout、sqlite3_busy_handler功能)3、当CPU运算能力超强时,一定会降低互斥的出现几率,但是互斥这种现象一定不会消失,因为互斥锁的出现就是为了保证数据的完整性,remember!
发表评论:
TA的推荐TA的最新馆藏[转]&

我要回帖

更多关于 sqlite创建内存数据库 的文章

 

随机推荐