2012-03-05 24 views
7

Tôi có một Android tùy chỉnh ContentProvider lưu trữ và truy xuất dữ liệu từ cơ sở dữ liệu SQLite.Các phương pháp hay nhất để đồng bộ hóa cơ sở dữ liệu SQL với máy chủ từ xa REST trên Android

Giả sử một trong các bảng DB có một cột _ID và một cột NAME và một nội dung như thế này:

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

này SQLite DB được giữ đồng bộ với cơ sở dữ liệu từ xa và dữ liệu mới được lấy định kỳ trên mạng. Các hoạt động có thể trên bàn như sau:

  1. hàng hiện tại có thể được xóa
  2. hàng mới có thể được thêm
  3. Cột TÊN hàng hiện tại có thể được sửa đổi

Hãy nay giả sử rằng tất cả các hoạt động có thể xảy ra cùng một lúc và sau khi tìm nạp một số dữ liệu cập nhật từ máy chủ từ xa, nội dung mới của bảng này phải được đặt như sau:

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

Có thể có hai cách tiếp cận khác nhau để thực hiện điều đó:

  1. Query cơ sở dữ liệu và kiểm tra từng hàng hiện có để xem nếu họ cần phải được cập nhật, sau đó thêm bất kỳ hàng mới và xóa bất kỳ hàng thiếu - mặc dù điều này phương pháp có thể hơi phức tạp trong trường hợp chúng tôi muốn cập nhật cơ sở dữ liệu bằng cách tiếp cận phân trang và không tìm nạp một mạng đơn lẻ
  2. Xóa toàn bộ bảng bằng một lệnh DELETE SQL đơn và sau đó thêm tất cả các hàng nhận được từ máy chủ

Trên Android, Tôi hiện đang thực hiện phương pháp thứ hai với hoạt động hàng loạt để tối đa hóa hiệu suất:

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); 

Đây có phải là phương pháp tốt nhất, hoặc phương pháp 1 (hoặc một số phương pháp khác) sẽ tốt hơn về hiệu suất ?

EDIT: ví dụ, lấy phương pháp 2, ghi đè ContentProvider#bulkInsert sử dụng giao dịch cơ sở dữ liệu có thể tăng tốc thao tác chèn hàng loạt rất nhiều: xem this question.

Trả lời

1

Tùy chọn tốt nhất yêu cầu triển khai API đúng - khi bạn nên lưu trữ một số db_version (int hoặc dấu thời gian của cập nhật lần cuối hoặc bất kỳ thứ gì).

Và trong khi máy chủ cập nhật phản hồi với dữ liệu và loại hoạt động - thêm, cập nhật, xóa.

+0

Tôi e rằng điều này là không thể. API REST của máy chủ chỉ trả về danh sách các mục trong một biểu diễn JSON và nó là khách hàng bất khả tri. Không có thông tin cụ thể về đồng bộ hóa nào có sẵn từ máy chủ. –

+1

Xóa tất cả và chèn các mục mới sau đó. – kzotin

+1

Vâng, tôi cũng nghĩ đây là lựa chọn duy nhất trong trường hợp này. Tôi chỉ nghĩ rằng nếu tôi cố gắng thuyết phục các chàng trai dịch vụ web thêm API đồng bộ hóa này, điều này sẽ thêm tính linh hoạt hơn nhiều. Neo có thể là ngày sửa đổi cuối cùng và một khách hàng có thể yêu cầu máy chủ cho tất cả các mục đã được thêm/sửa đổi/xóa sau một ngày cụ thể. Tuy nhiên, đối với các mục đã xóa, máy chủ cần theo dõi các mục đã xóa, nhưng làm cách nào?có thể không thực sự xóa bất kỳ mục nào nhưng chỉ đơn giản là đánh dấu chúng là "đã xóa" trong cơ sở dữ liệu? Kích thước DB sẽ tăng thêm sau đó cần thiết trong trường hợp này? –

Các vấn đề liên quan