由于sqlite对多进程操作支持效果不太理想,在项目中,为了避免频繁读写 文件数据库带来的性能损耗,我们可以采用操作sqlite内存数据库,并将内存数据库定时同步到文件数据库中的方法。

实现思路如下:

1、创建文件数据库;

2、创建内存数据库(文件数据库、内存数据库的内幕表结构需要一致);

3、在内存数据库中attach文件数据库,这样可以保证文件数据库中的内容在内存数据库中可见;

4、对于insert、select操作,在内存数据库中完成,对于delete、update操作,需要同时访问内存、文件数据库;

5、定时将内存数据库中的内容flush到文件数据库。

通过sqlite的cAPI实现代码如下:

const char* file_database_path = "/home/tom/test/database/filedb"; //文件数据库存放路径const char* sql_create_data = "CREATE TABLE testinfo (id TEXT PRIMARY KEY, message TEXT, offset INTEGER, timestamp INTEGER);";
const char* sql_insert_data = "INSERT OR REPLACE INTO MAIN.testinfo VALUES('%s', '%s', %d, %d);";
const char* sql_delete_data = "DELETE FROM MAIN.testinfo WHERE id = '%s'; DELETE FROM filedb.testinfo WHERE id = '%s';"; //删除数据库,需同时删除内存、文件数据库中的内容
const char* sql_update_data = "UPDATE MAIN.testinfo SET message = '%s', offset = %d, timestamp = %d where id = '%s'; UPDATE filedb.testinfo SET message = '%s', offset = %d, timestamp = %d where id = '%s';";//更新数据库,需同时更新内存、文件数据库中的内容
const char* sql_search_data = "SELECT * FROM MAIN.testinfo WHERE timestamp BETWEEN %d AND %d union SELECT * FROM testdb.testinfo WHERE timestamp BETWEEN %d AND %d;"; //查找数据库,将内存、文件数据库中查找出的内容合并
const char* sql_transfer_data = "INSERT OR REPLACE INTO filedb.testinfo SELECT * FROM testinfo;";   //将内存数据库中的信息同步到文件数据库中
const char* sql_delete_memory_table = "DELETE FROM testinfo;";   //内存数据库中的内容同步结束后,清空int InsertRecord(DATA_TYPE type, const char* id, const char* message, int offset, int timestamp)
{int      rc              =  0;char*    errMsg          =  NULL;char     sqlcmd[512]     =  {0};time_t   insertTimestamp =  0;snprintf(sqlcmd, sizeof(sqlcmd), sql_insert_data, id, message, offset, timestamp);rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);if (SQLITE_OK != rc) {fprintf(stderr, "cat't add record to memory database %s, sqlcmd=%s, err:%s\n", map_data_table[type].data_table_name, sqlcmd, errMsg);return -1;}return 0;
}int UpdateRecord(DATA_TYPE type, const char* id, const char* message, int offset, int timestamp)
{int      rc              = 0;char*    errMsg          = NULL;char     sqlCmd[512]  = {0};snprintf(sqlCmd, sizeof(sqlCmd), sql_update_data, message, offset, timestamp, id, message, offset, timestamp, id);rc = sqlite3_exec(memdb, sqlCmd, NULL, NULL, &errMsg);if (SQLITE_OK != rc) {fprintf(stderr, "cat't update record %s:%s\n", map_data_table[type].data_table_name, errMsg);return -1;}return 0;
}int DeleteRecord(DATA_TYPE type, const char* id)
{int      rc              =  0;char*    errMsg          =  NULL;char     sqlcmd[512]     =  {0};snprintf(sqlcmd, sizeof(sqlcmd), sql_delete_data, id,  id);rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);if (SQLITE_OK != rc) {fprintf(stderr, "cat't delete record %s:%s\n", map_data_table[type].data_table_name, errMsg);return -1;}return 0;
}int QueryMessage(DATA_TYPE type, int startTime, int endTime)
{int      rc              = 0;char     *errMsg         = NULL;sqlite3  *filedb         = NULL;char**   pRecord         = NULL;int      row             = 0;int      column          = 0;char     sqlcmd[512]     = {0};if (type > VEP_NELEMS(map_data_table) || type < 0) {return -1;}rc = sqlite3_open(file_database_path, &filedb);if (SQLITE_OK != rc) {fprintf(stderr, "cat't open database:%s\n", sqlite3_errmsg(filedb));sqlite3_close(filedb);return -1;}snprintf(sqlcmd, sizeof(sqlcmd), sql_search_data,  startTime, endTime,  startTime, endTime);rc = sqlite3_get_table(filedb, sqlcmd, &pRecord, &row, &column, &errMsg);if (SQLITE_OK != rc) {fprintf(stderr, "cat't get table from%s:%s\n", map_data_table[type].data_table_name, errMsg);return -1;}int i;printf("row = %d, column = %d\n", row, column);for(i = 0; i < 2*column; i++){printf("%s ", pRecord[i]);}printf("\n");return 0;
}//定时调用此函数将内存数据中的内容同步到文件数据库
int Flush(){int      i            = 0;int      rc           = 0;char*    errMsg       = NULL;char     sqlcmd[512]  = {0};snprintf(sqlcmd, sizeof(sqlcmd), sql_transfer_data);rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);if (SQLITE_OK != rc) {fprintf(stderr, "cat't transfer memory database %s to file databasede:%s\n", map_data_table[i].data_table_name, sqlite3_errmsg(memdb));sqlite3_close(memdb);return -1;}snprintf(sqlcmd, sizeof(sqlcmd), sql_delete_memory_table);rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);return 0;
}//创建文件数据库
int CreateDbOnFile()
{sqlite3 *db           = NULL;int      rc           = 0;char*    errMsg       = NULL;char     sqlcmd[512]  = {0};int      i            = 0;rc = sqlite3_open(file_database_path, &db);if (SQLITE_OK != rc) {fprintf(stderr, "cat't open database:%s\n", sqlite3_errmsg(db));sqlite3_close(db);return -1;}snprintf(sqlcmd, sizeof(sqlcmd), sql_create_data);rc = sqlite3_exec(db, sqlcmd, NULL, NULL, &errMsg);if (SQLITE_OK != rc) {fprintf(stderr, "cat't create file database testinfo:%s\n", errMsg);sqlite3_close(db);return -1;}sqlite3_close(db);return 0;
}//创建内存数据库
int CreateDbOnMemery()
{int      rc           = 0;char*    errMsg       = NULL;char     sqlcmd[512]  = {0};int      i            = 0;rc = sqlite3_open(":memory:", &memdb);if (SQLITE_OK != rc) {fprintf(stderr, "cat't open database:%s\n", sqlite3_errmsg(memdb));sqlite3_close(memdb);return -1;}snprintf(sqlcmd, sizeof(sqlcmd), sql_create_data);rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);if (SQLITE_OK != rc) {fprintf(stderr, "cat't create memory database %s\n", errMsg);sqlite3_close(memdb);return -1;}return 0;
}//解绑数据库
int DetachDb()
{int      rc           =  0;char*    errMsg       =  NULL;char     sqlcmd[512]  =  {0};snprintf(sqlcmd, sizeof(sqlcmd), "DETACH '%s'", "filedb");rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);if (SQLITE_OK != rc) {fprintf(stderr, "detach file database failed:%s:%s\n", file_database_path, errMsg);sqlite3_close(memdb);return -1;}return 0;
}//将文件数据库作为内存数据库的附加数据库
int AttachDb()
{int      rc           =  0;char*    errMsg       =  NULL;char     sqlcmd[512]  =  {0};snprintf(sqlcmd, sizeof(sqlcmd), "ATTACH '%s' AS %s", file_database_path, "filedb");rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);if (SQLITE_OK != rc) {fprintf(stderr, "cat't attach database %s:%s\n", file_database_path, errMsg);sqlite3_close(memdb);return -1;}return 0;
}//初始化数据库,分别创建文件数据库、内存数据库并把文件数据库attach到内存数据库上
int InitSqliteDb()
{int retval = 0;retval =  CreateDbOnFile();if (retval != 0) {return retval;}retval =  CreateDbOnMemery();if (retval != 0) {return retval;}retval =  AttachDb();if (retval != 0) {return retval;}return 0;
}

sqlite内存数据库和文件数据库的同步相关推荐

  1. Qt Sqlite内存数据库和文件数据库交互

    基础概念: 1.内存数据库标识":memory:": 2.[]中内容表示可选: 3.采用QSqlDatabase实现Sqlite的内存数据库和文件数据库交互. 一.将文件数据库加载 ...

  2. mysql备份至cos_宝塔面板网站文件/数据库定时同步备份至腾讯云COS设置

    本来老蒋这篇文章是要分享张戈同学关于利用腾讯云COS备份网站和数据库脚本工具的整理的,但是翻看之前的博文发现我们能用到的面板和工具包大部分都自带第三方云存储接口快速备份的.所以这篇文章延期到后面再去分 ...

  3. 文件数据库之sqlite 与内存数据库 redis

    内存数据库:大数据时代数据管理新宠 在 2012中国系统架构师大会上,笔者曾做过一份有关大数据的调查,其中一项"在众多的技术趋势中,您所关注的数据管理的新技术是什么?"的调查结果中 ...

  4. 轻便的客户端本地文件数据库 SQLite

    想在客户端程序中暂存一些数据(数据库较大,类别较多),不想用文件,因其不便于检索,操作也麻烦.于是去找一种轻便的文件数据库,看了一下,先看中了几种,1,Berkeley DB(开源,一些条件下收费,且 ...

  5. Apache NIFI 安装 ● 操作 ● 文件同步 ● oracle 数据库增量同步实例讲解

    nifi简介 nifi背景 NiFi之前是在美国国家安全局(NSA)开发和使用了8年的一个可视化.可定制的数据集成产品.2014年NSA将其贡献给了Apache开源社区,2015年7月成功成为Apac ...

  6. phpcms v9电脑pc站+手机wap移动端双模板共用数据库数据同步可同步生成静态文件

    phpcms v9电脑pc站+手机wap移动端双模板共用数据库数据同步可同步生成静态文件,并且电脑站和手机站网址页面一一对应,非插件,程序二次开发版. 详情如下: 1.phpcms v9电脑版+手机版 ...

  7. sqlite管理工具_Liquibase 数据库版本管理工具:1.安装

    1.Liquibase 是什么 粘一段官方的解释 Track, version, and deploy database changes 跟踪.管理和应用数据库变化 说白了,就是一个将你的数据库脚本转 ...

  8. SymmetricDS 数据库双向同步开源软件入门

    一句话概括该软件:SymmetricDS是一个文件和数据库同步软件,开源的,支持多主复制,同步时过滤和在异构的网络环境中进行数据转换传输.它支持单向和双向上的多个订阅者,异步的数据复制. 以下是从CS ...

  9. 内存数据库、磁盘数据库、分布式数据库区别

    内存数据库 传统的数据库管理系统把所有数据都放在磁盘上进行管理,所以称作磁盘数据库(DRDB: Disk-Resident Database).磁盘数据库因为磁头机械运动及系统调用因素导致速度降低,后 ...

  10. Sqlite进阶之--附加数据库关联查询以及Pragma的相关使用

    数据库连接 基本的 Data Source=c:\mydb.db;Version=3; 此类库不支持版本 2. 内存数据库 Data Source=:memory:;Version=3;New=Tru ...

最新文章

  1. Apache Solr入门教程(初学者之旅)
  2. 如何给Lombok Builder提供默认值
  3. 进程线程002 等待链表 调度链表
  4. 漫画说算法--动态规划算法二(绝对通俗易懂,非常棒)
  5. 计算机研究生怎样提高英语水平,英语对计算机专业的重要性及如何提高英语水平...
  6. 2019 中国.NET 开发者峰会正式启动
  7. 百兆工业交换机与千兆工业交换机如何计算码率?
  8. hdu 2609 How many(最小表示法)
  9. centos7安装terminator
  10. java web导出excel表格,java 网页导出excel表格数据-java 将页面内容写入excel文件中并可以将其下载到......
  11. 实测macOS双开微信客户端
  12. java 7新特性-TWR(Try-with-resources)
  13. 【ACPC2013】马里奥赛车(01背包)
  14. excel多条件计数python_Excel统计满足条件的不重复值个数的8种方法,第三种方法最适合新手!我真的入门了!...
  15. 快手裁员30%,大部分年薪超100万!揭露职场真相:思考的深度,决定职场的高度...
  16. python制作英语字典_Python爬虫之自制英汉字典
  17. python识别颜色并提取轮廓_pythonopencv检测并提取目标颜色
  18. Pytorch 学习率衰减 之 余弦退火与余弦warmup 自定义学习率衰减scheduler
  19. 查询mysql 的内存使用_mysql查看内存使用情况
  20. Unable to open debugger port (127.0.0.1:51816): java.net.BindException “Address already in use: NET_

热门文章

  1. Linux程序设计——shell
  2. Javashop-B2B2C多店铺系统,Javashop B2C开源电商系统下载
  3. RSLogix 5000下载程序方法
  4. Struts2——OGNL表达式
  5. vrep小车避障算法_V-REP 多车道巡线与避障
  6. MAC终端命令颜色设置
  7. zendstudio13.6配置xdebug调试
  8. zend studio php插件,Zend Studio使用技巧两则 zend studio安装 zend studio 插件 zend studio 中文...
  9. mysql服务器版本手册_MySQL中文参考手册——与MySQL服务器连接
  10. 三分钟细数几款可视化前端开发工具