美文网首页数据库操作实用技术
iOS APP新版本升级数据库

iOS APP新版本升级数据库

作者: so_what | 来源:发表于2017-03-17 16:41 被阅读73次

    我们常常会在APP中使用数据库,但是由于版本迭代问题,数据库的结构可能会发生变更,这时候需要对用户原始数据进行保留。这是一个很正常的需求,有人可能会简单粗暴的把数据库删除,重新创建,把数据重新插进去。如果表很多,里面只有一张表的数据结构发生变化了,这种做法真的好么?下面我会讲下我的思路,分享交流下。
    简单的流程分析,共四步:

    • 把要更改结构的那张表 A1 改名为 tempA1
    • 创建一张当前版本需要结构的表A1
    • 将tempA1 里面的有效数据 迁移到 A1中
    • 删除 tempA1

    以上简单的思路数据库就更改完毕了。
    这时引出了第二个问题,如果用户的app没有及时更新,错过了好几个版本的数据库更改,以上数据库更改不可能会一步到位了。化简为繁,一步一步的更改数据库表结构,直到更改到最后一次。下面看代码。

    typedef NS_ENUM(NSInteger, DBVersion) {
        DBVersionV1,
        DBVersionV2,    //历史版本
        DBVersionV3,    //当前版本
    };
    
    static NSString *const DBVersionNum  = @"DBVersionNum";
    static NSString *const dbPath = @"\tmp\tmp.db";     //数据库地址
    
    static NSString *const createTable = @"create table if not exists  t1("
    "id  integer PRIMARY KEY AUTOINCREMENT NOT NULL,"
    "name char(50),"
    "sex char(4),"
    "recordDate  TIMESTAMP default (datetime('now', 'localtime')))";
    

    首先定义了一个枚举,标识着当前一共有多少数据库版本变更。(客户端数据库结构更改不会太频繁,如果更改太快,可能意味着初期表设计不合理),此次模拟共三个版本的数据库。

    - (instancetype)init{
        if (self = [super init]) {
            _queue = [FMDatabaseQueue databaseQueueWithPath:dbPath];
        }
        return self;
    }
    

    采用FMDatabaseQueue 进行数据库操作的管理。

    /*
     *  需要初始化表结构时,调用此方法
     */
    - (void)newDBVersionInit{
        if (![[NSUserDefaults standardUserDefaults] objectForKey:DBVersionNum]) {
            //系统之前没有数据库 新建立表。
            [self createTables];
        }else{
            DBVersion ver = [[[NSUserDefaults standardUserDefaults] objectForKey:DBVersionNum] integerValue];
            switch (ver) {
                case DBVersionV1:{
                    [self v1ToV2];
                }
                case DBVersionV2:{
                    [self v2Tov3];
                }
                case DBVersionV3:{
    
                }
                    break;
                default:
                    break;
            }
        }
    }
    

    在这里判断DBVersionNum系统之前是否存储过,
    没有存储说明是第一次安装,则进行首次创建表处理。
    有说明之前数据库存在,进行数据库表结构更改。如果是v1版本的数据库 先从v1升级到v2,在从v2升级到v3,以此类推。

    /*
     *  创建新表
     */
    - (void)createTables{
        [_queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            @try {
                [db executeUpdate:createTable];
            }
            @catch (NSException *exception) {
                *rollback = YES;
            }
        }];
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInteger:DBVersionV3] forKey:DBVersionNum];
    }
    

    把 DBVersionNum的值写为V3版本 方便下次对比。

    /*
     *  版本1 向 版本2 数据迁移
     */
    - (void)v1ToV2{
    
        [_queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
            @try {
    
                //将原始表名T1 修改为 tempT1
                NSString *renameString = @"alter table t1 rename to tempT1";
                [db executeUpdate:renameString];
    
                //创建新表T1(V2版本的新表创建)
                [db executeUpdate:createTable];
    
                //迁移数据
                NSString *toString = @"insert into t1(name,sex)  select name,sex from tempT1";
                [db executeUpdate:toString];
    
                //删除tempT1临时表
                NSString *dropTableStr1 = @"drop table tempT1";
                [db executeUpdate:dropTableStr1];
            }
            @catch (NSException *exception) {
                *rollback = YES;
            }
        }] ;
    
    
        [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInteger:DBVersionV2] forKey:DBVersionNum];
    }
    
    //V2升级到V3
    - (void)v2Tov3{
     [_queue inTransaction:^(FMDatabase *db, BOOL *rollback) {
    //和 v1ToV2 流程一样
     }] ;
     [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithInteger:DBVersionV3] forKey:DBVersionNum];
    }
    

    上文提到的数据迁移流程就是如此。
    如有更好的方案可以互相交流。

    相关文章

      网友评论

      • LD_左岸:"recordDate TIMESTAMP default (datetime('now', 'localtime'))这个不写是不是也可以
      • LD_左岸:楼主有没有demo让学习一下
      • 6c4b5fcc86cd::heart_eyes::heart_eyes::heart_eyes:大神就是大神

      本文标题:iOS APP新版本升级数据库

      本文链接:https://www.haomeiwen.com/subject/gwienttx.html