FMDB大量寫入數據使用注意點


關於FMDB最基本的使用我們就不在說了,這個網上大把的文章介紹,我就在這里總結幾點我最近在寫一個小東西的時候注意到的一點點東西:

 

一: 怎么看真機上SQLite數據庫

      我們在開發的過程中肯定有使用到真機測試,不知道會不會有小伙伴有好奇心想看看在真機環境中我們創建的數據庫可視化的數據是什么樣子呢。當然你可以通過SQ語句去查看,當然我們也有辦法直接像看表格數據一樣查看它。

      1、XCode  -  Window  -  Devices and Simlators

      2、選中你的手機  -  選中你的App  -  下面設置按鈕 (如下圖所示)

      3、Download Container...

      

      4、最好保存桌面,方便我們查看

      然后你桌面就會有一份 .xcappdata 文件了,這時候你再“顯示包內容” 就可以看到里面有一份 AppData 和 AppDataInfo.plist 文件,這時候你 AppData - Documents

就能看到你的 X.sqlite 數據庫了。

      查看這份數據庫我使用的是一個叫SQLite的國外軟件的破解版,直接可視化看到,大概界面如下面這樣:

      當然還有網上很多人說的 火狐瀏覽器的 SQLite Manager 這個擴展,但由於我的火狐瀏覽器比較新,就沒辦法像以前那樣可視化的查看了,你現在安裝擴展之后是下面這樣子的。關於它現在的簡單的使用我有標注出來,現在用它查看沒沒法直接可視化的,但你可以通過下面SQ語句操作該數據庫。

 

關於FMDB最基本的使用我們就不在說了,這個網上大把的文章介紹,我就在這里總結幾點我最近在寫一個小東西的時候注意到的一點點東西:

   

二:要是你要寫入大量的數據

      1、引入的它叫做“事務”,事務主要是解決數據量多的耗時操作。

    在數據庫操作中,所謂事務是用戶定義的一個數據庫操作序列,這些操作要么全做要么全不做,是一個不可分割的工作單位。例如,在關系數據庫中,一個事務可以是一條SQL語句、一組SQL語句或整個程序。
  事務和程序是兩個概念。一般地講,一個程序中包含多個事務。
  事務的開始與結束可以由用戶顯式控制。如果用戶沒有顯式地定義事務,則由 DBMS 按缺省規定自動划分

      在 SQL 語言中,定義事務的語句有三條:

        BEGIN TRANSACTION         [trænˈzækʃn]
        COMMIT TRANSACTION
        ROLLBACK  [ˈroʊlbæk]  TRANSACTION

      2、事務我們這樣介紹概念,那它的優點又有那些呢?

           數據庫中的插入操作是比較耗時的,假如我們一次性在主線程插入幾百幾千條數據,由於比較較慢就會造成主線程阻塞。那么這時候可以開啟一個事物來進行操作。
       數據庫以文件的形式存在磁盤中,每次訪問時都要打開一次文件,如果對數據庫進行大量的操作,就很慢。當用事物的形式提交,開始事務后,進行的大量操作語句都   保存在內存中,當提交時才全部寫入數據庫,此時,數據庫文件也只用打開一次。如果操作錯誤,還可以回滾事務。
 
      3、事務的特性
           Atomic  [əˈtɑːmɪk](原子性)事務中包含的操作被看做一個邏輯單元,這個邏輯單元中的操作要么全部成功,要么全部失敗。事務中的所有元素作為一個整體提交或回滾,事務的個元素是不可分的,事務是一個完整操作。
       Consistency [kənˈsɪstənsi](一致性)只有合法的數據可以被寫入數據庫,否則事務應該將其回滾到最初狀態。事物完成時,數據必須是一致的,也就是說,和事物開始之前,數據存儲中的數據處於一致狀態。保證數據的無損。
       Lsolation(隔離性)事務允許多個用戶對同一個數據進行並發訪問,而不破壞數據的正確性和完整性。同時,並行事務的修改必須與其他並行事務的修改相互獨立。對數據進行修改的多個事務是彼此隔離的。這表明事務必須是獨立的,不應該以任何方式以來於或影響其他事務。
       Durability  [ˌdjʊərəˈbɪləti]  durable
(持久性)事務結束后,事務處理的結果必須能夠得到固化。事務完成之后,它對於系統的影響是永久的,該修改即使出現系統故障也將一直保留,真實的修改了數據庫。

      所以事務是線程安全的
 
      EG:下面就是一個簡單的數據存儲關於FMDB事務的例子

      

/**
 debug 
 @param title   統計標題
 @param content 統計內容JSON數據
 */
-(void)DebugSensorsAnalyticsShowWithDoraemonKit:(NSString *)title andParments:(NSString * )content{
    
    // 獲得Documents目錄路徑
    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *dbPath = [documentsPath stringByAppendingPathComponent:@"SensorsAnalytics.sqlite"];
    debugLog(@"!!!  debug  !!! dbPath = %@",dbPath);
    //創建數據庫
    _dataBase = [FMDatabase databaseWithPath:dbPath];
    if (![_dataBase open]) {
        debugLog(@"SensorsAnalytics open fail");
        return;
    }
    //創建表  currenthour 比較時間 一小時前的刪除 不然數據過大
    NSString * sql = @"create table if not exists sensorsAnalytics ('time' TEXT NOT NULL,'title' TEXT NOT NULL, 'content' TEXT NOT NULL,'hour' TEXT NOT NULL)";
    BOOL result = [_dataBase executeUpdate:sql];
    if (result) {
        debugLog(@"create sensorsAnalytics table success");
    }
    
    [_dataBase beginTransaction];//開啟一個事務
    BOOL isRollBack = NO;
    @try {
        NSString *currentTime = [self getCurrentTimes];
        NSString *currenthour = [self getCurrentHour];
        BOOL insertResult = [_dataBase executeUpdate:@"insert into 'sensorsAnalytics'(time,title,content,hour) values(?,?,?,?)" withArgumentsInArray:@[currentTime,title,content,currenthour]];
        if (insertResult) {
            debugLog(@"insert into 'sensorsAnalytics' success");
        }
        // 把一個小時前的數據刪除
        BOOL deleteResult = [_dataBase executeUpdate:[NSString stringWithFormat:@"delete from sensorsAnalytics where hour < %@",currenthour]];
        if (deleteResult) {
            debugLog(@"delete from 'sensorsAnalytics' success");
        }
        
    } @catch (NSException *exception) {
        isRollBack = YES;
        [_dataBase rollback];   // 回滾
    } @finally {
        if (!isRollBack) {
            [_dataBase commit]; // 沒有錯誤一次性提交
        }
    }
    [_dataBase close];
}

-(NSString*)getCurrentTimes{
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"MM-dd HH:mm:ss"];
    NSDate *datenow = [NSDate date];
    NSString *currentTimeString = [formatter stringFromDate:datenow];
    return currentTimeString;
}

-(NSString *)getCurrentHour{
    
    NSDate *now = [NSDate date];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSUInteger unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
    NSDateComponents *dateComponent = [calendar components:unitFlags fromDate:now];
    NSString * hour =  [NSString stringWithFormat:@"%ld",(long)[dateComponent hour]];
    return hour;
}

 

      參考學習鏈接: FMDB寫入大量數據的處理方法

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM