加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

SQLite使用日志

发布时间:2020-12-12 23:38:36 所属栏目:百科 来源:网络整理
导读:最近又测试了一下内存数据库SQLite,发现功能增强了好多,比如多线程支持(用文件锁的方式实现的),并且也可以全内存化(用":memory:"的方式打开即可)了。 由于多线程的支持是通过操作系统文件锁的方式实现的,所以当以全内存数据库(即无磁盘文件)的方式

最近又测试了一下内存数据库SQLite,发现功能增强了好多,比如多线程支持(用文件锁的方式实现的),并且也可以全内存化(用":memory:"的方式打开即可)了。

由于多线程的支持是通过操作系统文件锁的方式实现的,所以当以全内存数据库(即无磁盘文件)的方式打开SQLite时,就不支持多线程了,必须自行实现读写锁以互斥,推荐使用ACE读写锁。

由于SQLite的锁是文件锁的方式实现,所以它不能实现表级锁,而只能是全数据库文件锁。另外,线程间不能以共享数据库指针的方式实现共享,而要分别打开一个SQLite实例,互斥机制才能正确的工作。所以,如果你使用":memory:"的方式打开SQLite,不同线程之间很难共享一个数据库(每一个线程都打开了一个全新的实例),如果你简单的通过指针来共享,又会造成互斥机制不能正常工作,这个矛盾我还没有找到解决办法。


经过测试,发现SQLite和自己实现的数据结构(比如STL)的性能还是有一定差距,比如我遍历一个query的结果集的时间通常在几十毫秒(时间主要和记录集大小有关,几十毫秒是几十到几百条记录的结果),不过考虑到方便的存储和实现索引﹑事务等功能,这个开销还是值得的。

使用时注意如果你要使用显示事务(默认的DML语句操作使用autocommit模式),要自行控制重试,而不能像一般的网络数据库那样,由数据库连接进行阻塞等待,SQLite在你申请事务时会直接返回,不管成功与否;但你可以用下面的方法自行控制:

  1. intiRet;
  2. do
  3. {
  4. iRet=CppSQLite3DB::exeDML("beginIMMEDIATE;");
  5. if(iRet==SQLITE_BUSY)
  6. Sleep(20);
  7. }while(iRet==SQLITE_BUSY);

测试时,我用到了几个CodeProject网站上发表的封装类:
1)ODBC的封装类CODBCDatabase,CODBCRecordset
2)SQLite的封装类CppSQLite
3)对象池的封装类PoolMgr

这些类都是比较好的封装类,可以轻易地集成进自己的应用。我还特地实现了几个直接通过ODBC把网络数据库的内容转到SQLite的通用函数,这样,可以轻易地进行本地应用的数据初始化(特别当这些初始数据来自于网络数据库时),还可以用几句话就为这些数据建立合适的索引,起到真正的内存数据库的作用。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读