• 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 ", 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 ", 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 ", 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 ", 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 ", map_data_table[type].data_table_name, errMsg);  
    87.         return -1;  
    88.     }  
    89.       
    90.     int i;  
    91.     printf("row = %d, column = %d ", row, column);  
    92.     for(i = 0; i < 2*column; i++)  
    93.     {  
    94.         printf("%s ", pRecord[i]);  
    95.     }  
    96.     printf(" ");  
    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 ", 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 ", 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 ", 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 ", 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 ", 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 ", 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 ", 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. }  
  • 相关阅读:
    javascript 编码规范
    javascript 减少全部变量
    轮播图 jquery
    SVN MAC
    php excel
    php email
    查看网站后台
    linux 下载文件
    第6周小组作业:软件测试和评估
    第4周小组作业:WordCount优化
  • 原文地址:https://www.cnblogs.com/soqu36/p/9153855.html
Copyright © 2020-2023  润新知