7

我有一個自定義Android ContentProvider,它存儲和檢索SQLite數據庫中的數據。在SQL上同步SQL數據庫和REST遠程服務器的最佳實踐

讓我們假設數據庫表中的一個具有_ID列和NAME列,像這樣的內容:

|==========|==========| 
| _ID | NAME | 
|==========|==========| 
| 1  | d1 | 
| 2  | d2 | 
| 3  | d3 | 
| 4  | d4 | 
|==========|==========| 

這SQLite的數據庫是保持同步遠程數據庫和新的數據被取出週期性過網絡。是 桌子上的可能的操作如下:

  1. 存在的行刪除即可
  2. 新行可以添加
  3. 現有行的名稱列可以被修改

現在,讓我們假定所有可能的操作都是同時發生的,並且在從遠程服務器獲取一些最新數據之後,該表的新內容必須設置如下:

|==========|==========| 
| _ID | NAME | 
|==========|==========| 
| 1  | d7 | 
| 3  | d3 | 
| 4  | d6 | 
| 5  | d5 | 
|==========|==========| 

可以有兩種不同的方法來做到這一點:

  1. 查詢數據庫,並檢查每個現有行,看看他們是否需要更新,然後再添加任何新行,並刪除任何缺失行 - 儘管這方法可能有點棘手,如果我們想要使用分頁方法更新數據庫而不是使用單個網絡獲取
  2. 使用單個DELETE SQL命令刪除整個表,然後添加從服務器接收的所有行

在Android上,我目前正在實施與批處理操作第二種方法性能發揮到極致:

final ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(); 

// with this URI, the content provider deletes all rows 
operations.add(ContentProviderOperation.newDelete(Users.CONTENT_URI).build()); 

final ContentValues values = new ContentValues(); 
values.put(ID_COLUMN, 1); 
values.put(NAME_COLUMN, "d7"); 
values.put(ID_COLUMN, 3); 
values.put(NAME_COLUMN, "d3"); 
values.put(ID_COLUMN, 4); 
values.put(NAME_COLUMN, "d6"); 
values.put(ID_COLUMN, 5); 
values.put(NAME_COLUMN, "d5"); 

operations.add(ContentProviderOperation.newInsert(Users.CONTENT_URI).withValues(values).build()); 

getApplicationContext().getContentResolver().applyBatch(MyContentProvider.AUTHORITY, operations); 

這是最好的方法,或將方法1(或其他方式)在性能方面更好?

編輯:例如,採取方法2,使用數據庫事務的重寫的ContentProvider#bulkInsert可以加快批量插入操作的速度:請參閱this question

回答

1

最好的選擇需要適當的API實現 - 當你應該存儲一些db_version(int或最後更新的時間戳,或其他)。

在更新服務器響應數據和操作類型 - 添加,更新,刪除。

+0

恐怕這是不可能的。服務器REST API僅返回JSON表示中的項目列表,並且它是客戶端不可知的。服務器不提供同步特定的信息。 – 2012-03-05 11:53:56

+1

然後刪除全部並插入新項目。 – kzotin 2012-03-05 13:34:37

+1

是的,我也認爲這是這種情況下唯一的選擇。我只是想,如果我設法說服Web服務人員添加這個同步API,這將增加更多的靈活性。該錨點可能是最後一次修改日期,客戶端可能會要求服務器查找指定日期後添加/修改/刪除的所有項目。但是,對於已刪除的項目,服務器需要跟蹤已刪除的項目,但是如何?也許不是真的刪除任何項目,而只是將它們標記爲數據庫中的「已刪除」?在這種情況下,數據庫大小不會增長多少? – 2012-03-05 13:50:28

相關問題