7
我有一個自定義Android ContentProvider
,它存儲和檢索SQLite數據庫中的數據。在SQL上同步SQL數據庫和REST遠程服務器的最佳實踐
讓我們假設數據庫表中的一個具有_ID
列和NAME
列,像這樣的內容:
|==========|==========|
| _ID | NAME |
|==========|==========|
| 1 | d1 |
| 2 | d2 |
| 3 | d3 |
| 4 | d4 |
|==========|==========|
這SQLite的數據庫是保持同步遠程數據庫和新的數據被取出週期性過網絡。是 桌子上的可能的操作如下:
- 存在的行刪除即可
- 新行可以添加
- 現有行的名稱列可以被修改
現在,讓我們假定所有可能的操作都是同時發生的,並且在從遠程服務器獲取一些最新數據之後,該表的新內容必須設置如下:
|==========|==========|
| _ID | NAME |
|==========|==========|
| 1 | d7 |
| 3 | d3 |
| 4 | d6 |
| 5 | d5 |
|==========|==========|
可以有兩種不同的方法來做到這一點:
- 查詢數據庫,並檢查每個現有行,看看他們是否需要更新,然後再添加任何新行,並刪除任何缺失行 - 儘管這方法可能有點棘手,如果我們想要使用分頁方法更新數據庫而不是使用單個網絡獲取
- 使用單個
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。
恐怕這是不可能的。服務器REST API僅返回JSON表示中的項目列表,並且它是客戶端不可知的。服務器不提供同步特定的信息。 – 2012-03-05 11:53:56
然後刪除全部並插入新項目。 – kzotin 2012-03-05 13:34:37
是的,我也認爲這是這種情況下唯一的選擇。我只是想,如果我設法說服Web服務人員添加這個同步API,這將增加更多的靈活性。該錨點可能是最後一次修改日期,客戶端可能會要求服務器查找指定日期後添加/修改/刪除的所有項目。但是,對於已刪除的項目,服務器需要跟蹤已刪除的項目,但是如何?也許不是真的刪除任何項目,而只是將它們標記爲數據庫中的「已刪除」?在這種情況下,數據庫大小不會增長多少? – 2012-03-05 13:50:28