sqlite内存数据库和文件数据库的同步[转]

 

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

实现思路如下:

1、创建文件数据库;

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

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

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

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

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

[cpp]  view plain  copy
 
  1. const char* file_database_path = "/home/tom/test/database/filedb"; //文件数据库存放路径  
  2.   
  3. const char* sql_create_data = "CREATE TABLE testinfo (id TEXT PRIMARY KEY, message TEXT, offset INTEGER, timestamp INTEGER);";  
  4. const char* sql_insert_data = "INSERT OR REPLACE INTO MAIN.testinfo VALUES('%s', '%s', %d, %d);";  
  5. const char* sql_delete_data = "DELETE FROM MAIN.testinfo WHERE id = '%s'; DELETE FROM filedb.testinfo WHERE id = '%s';"; //删除数据库,需同时删除内存、文件数据库中的内容  
  6. 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';";//更新数据库,需同时更新内存、文件数据库中的内容  
  7. 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;"; //查找数据库,将内存、文件数据库中查找出的内容合并  
  8. const char* sql_transfer_data = "INSERT OR REPLACE INTO filedb.testinfo SELECT * FROM testinfo;";   //将内存数据库中的信息同步到文件数据库中  
  9. const char* sql_delete_memory_table = "DELETE FROM testinfo;";  //内存数据库中的内容同步结束后,清空  
  10.   
  11.   
  12. int InsertRecord(DATA_TYPE type, const char* id, const char* message, int offset, int timestamp)  
  13. {  
  14.     int      rc              =  0;  
  15.     char*    errMsg          =  NULL;  
  16.     char     sqlcmd[512]     =  {0};  
  17.     time_t   insertTimestamp =  0;  
  18.   
  19.     snprintf(sqlcmd, sizeof(sqlcmd), sql_insert_data, id, message, offset, timestamp);  
  20.     rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);  
  21.     if (SQLITE_OK != rc) {  
  22.         fprintf(stderr, "cat't add record to memory database %s, sqlcmd=%s, err:%s\n", map_data_table[type].data_table_name, sqlcmd, errMsg);  
  23.         return -1;  
  24.     }  
  25.       
  26.     return 0;  
  27. }  
  28.   
  29. int UpdateRecord(DATA_TYPE type, const char* id, const char* message, int offset, int timestamp)  
  30. {  
  31.     int      rc              = 0;  
  32.     char*    errMsg          = NULL;  
  33.     char     sqlCmd[512]  = {0};  
  34.   
  35.     snprintf(sqlCmd, sizeof(sqlCmd), sql_update_data, message, offset, timestamp, id, message, offset, timestamp, id);  
  36.     rc = sqlite3_exec(memdb, sqlCmd, NULL, NULL, &errMsg);  
  37.     if (SQLITE_OK != rc) {  
  38.         fprintf(stderr, "cat't update record %s:%s\n", map_data_table[type].data_table_name, errMsg);  
  39.         return -1;  
  40.     }  
  41.   
  42.     return 0;  
  43. }  
  44.   
  45. int DeleteRecord(DATA_TYPE type, const char* id)  
  46. {  
  47.     int      rc              =  0;  
  48.     char*    errMsg          =  NULL;  
  49.     char     sqlcmd[512]     =  {0};  
  50.   
  51.     snprintf(sqlcmd, sizeof(sqlcmd), sql_delete_data, id,  id);  
  52.     rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);  
  53.     if (SQLITE_OK != rc) {  
  54.         fprintf(stderr, "cat't delete record %s:%s\n", map_data_table[type].data_table_name, errMsg);  
  55.         return -1;  
  56.     }  
  57.   
  58.     return 0;  
  59. }  
  60.   
  61. int QueryMessage(DATA_TYPE type, int startTime, int endTime)  
  62. {  
  63.     int      rc              = 0;  
  64.     char     *errMsg         = NULL;  
  65.     sqlite3  *filedb         = NULL;  
  66.     char**   pRecord         = NULL;  
  67.     int      row             = 0;  
  68.     int      column          = 0;  
  69.     char     sqlcmd[512]     = {0};  
  70.   
  71.     if (type > VEP_NELEMS(map_data_table) || type < 0) {  
  72.         return -1;  
  73.     }  
  74.   
  75.     rc = sqlite3_open(file_database_path, &filedb);  
  76.     if (SQLITE_OK != rc) {  
  77.         fprintf(stderr, "cat't open database:%s\n", sqlite3_errmsg(filedb));  
  78.         sqlite3_close(filedb);  
  79.         return -1;  
  80.     }  
  81.   
  82.     snprintf(sqlcmd, sizeof(sqlcmd), sql_search_data,  startTime, endTime,  startTime, endTime);  
  83.       
  84.     rc = sqlite3_get_table(filedb, sqlcmd, &pRecord, &row, &column, &errMsg);  
  85.     if (SQLITE_OK != rc) {  
  86.         fprintf(stderr, "cat't get table from%s:%s\n", map_data_table[type].data_table_name, errMsg);  
  87.         return -1;  
  88.     }  
  89.       
  90.     int i;  
  91.     printf("row = %d, column = %d\n", row, column);  
  92.     for(i = 0; i < 2*column; i++)  
  93.     {  
  94.         printf("%s ", pRecord[i]);  
  95.     }  
  96.     printf("\n");  
  97.   
  98.     return 0;  
  99. }  
  100.   
  101. //定时调用此函数将内存数据中的内容同步到文件数据库  
  102. int Flush(){  
  103.     int      i            = 0;  
  104.     int      rc           = 0;  
  105.     char*    errMsg       = NULL;  
  106.     char     sqlcmd[512]  = {0};  
  107.   
  108.     snprintf(sqlcmd, sizeof(sqlcmd), sql_transfer_data);  
  109.     rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);  
  110.     if (SQLITE_OK != rc) {  
  111.         fprintf(stderr, "cat't transfer memory database %s to file databasede:%s\n", map_data_table[i].data_table_name, sqlite3_errmsg(memdb));  
  112.         sqlite3_close(memdb);  
  113.         return -1;  
  114.     }  
  115.     snprintf(sqlcmd, sizeof(sqlcmd), sql_delete_memory_table);  
  116.     rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);  
  117.   
  118.     return 0;  
  119. }  
  120.   
  121. //创建文件数据库  
  122. int CreateDbOnFile()  
  123. {  
  124.     sqlite3 *db           = NULL;  
  125.     int      rc           = 0;  
  126.     char*    errMsg       = NULL;  
  127.     char     sqlcmd[512]  = {0};  
  128.     int      i            = 0;  
  129.   
  130.     rc = sqlite3_open(file_database_path, &db);  
  131.     if (SQLITE_OK != rc) {  
  132.         fprintf(stderr, "cat't open database:%s\n", sqlite3_errmsg(db));  
  133.         sqlite3_close(db);  
  134.         return -1;  
  135.     }  
  136.       
  137.     snprintf(sqlcmd, sizeof(sqlcmd), sql_create_data);  
  138.     rc = sqlite3_exec(db, sqlcmd, NULL, NULL, &errMsg);  
  139.     if (SQLITE_OK != rc) {  
  140.         fprintf(stderr, "cat't create file database testinfo:%s\n", errMsg);  
  141.         sqlite3_close(db);  
  142.         return -1;  
  143.     }  
  144.   
  145.     sqlite3_close(db);  
  146.     return 0;  
  147. }  
  148.   
  149. //创建内存数据库  
  150. int CreateDbOnMemery()  
  151. {  
  152.     int      rc           = 0;  
  153.     char*    errMsg       = NULL;  
  154.     char     sqlcmd[512]  = {0};  
  155.     int      i            = 0;  
  156.   
  157.     rc = sqlite3_open(":memory:", &memdb);  
  158.     if (SQLITE_OK != rc) {  
  159.         fprintf(stderr, "cat't open database:%s\n", sqlite3_errmsg(memdb));  
  160.         sqlite3_close(memdb);  
  161.         return -1;  
  162.     }  
  163.       
  164.     snprintf(sqlcmd, sizeof(sqlcmd), sql_create_data);  
  165.     rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);  
  166.     if (SQLITE_OK != rc) {  
  167.         fprintf(stderr, "cat't create memory database %s\n", errMsg);  
  168.         sqlite3_close(memdb);  
  169.         return -1;  
  170.     }  
  171.   
  172.     return 0;  
  173. }  
  174.   
  175. //解绑数据库  
  176. int DetachDb()  
  177. {  
  178.     int      rc           =  0;  
  179.     char*    errMsg       =  NULL;  
  180.     char     sqlcmd[512]  =  {0};  
  181.   
  182.     snprintf(sqlcmd, sizeof(sqlcmd), "DETACH '%s'", "filedb");  
  183.     rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);  
  184.     if (SQLITE_OK != rc) {  
  185.         fprintf(stderr, "detach file database failed:%s:%s\n", file_database_path, errMsg);  
  186.         sqlite3_close(memdb);  
  187.         return -1;  
  188.     }  
  189.   
  190.     return 0;  
  191. }  
  192.   
  193. //将文件数据库作为内存数据库的附加数据库  
  194. int AttachDb()  
  195. {  
  196.     int      rc           =  0;  
  197.     char*    errMsg       =  NULL;  
  198.     char     sqlcmd[512]  =  {0};  
  199.   
  200.     snprintf(sqlcmd, sizeof(sqlcmd), "ATTACH '%s' AS %s", file_database_path, "filedb");  
  201.     rc = sqlite3_exec(memdb, sqlcmd, NULL, NULL, &errMsg);  
  202.     if (SQLITE_OK != rc) {  
  203.         fprintf(stderr, "cat't attach database %s:%s\n", file_database_path, errMsg);  
  204.         sqlite3_close(memdb);  
  205.         return -1;  
  206.     }  
  207.   
  208.     return 0;  
  209. }  
  210.   
  211. //初始化数据库,分别创建文件数据库、内存数据库并把文件数据库attach到内存数据库上  
  212. int InitSqliteDb()  
  213. {  
  214.     int retval = 0;  
  215.   
  216.     retval =  CreateDbOnFile();  
  217.     if (retval != 0) {  
  218.         return retval;  
  219.     }  
  220.   
  221.     retval =  CreateDbOnMemery();  
  222.     if (retval != 0) {  
  223.         return retval;  
  224.     }  
  225.   
  226.     retval =  AttachDb();  
  227.     if (retval != 0) {  
  228.         return retval;  
  229.     }  
  230.   
  231.     return 0;  
  232. }  

猜你喜欢

转载自www.cnblogs.com/soqu36/p/9153855.html