2012-11-27 19 views
12

任何人對如何實現既使用localStorage的和REST遠程存儲數據持久層的任何意見或引用:架構數據層同時使用localStorage的和REST的遠程服務器

一定的數據客戶端使用localStorage存儲(使用ember-data索引DB適配器)。本地存儲的數據與遠程服務器同步(使用ember-data RESTadapter)。

服務器收集來自客戶端的所有數據。使用mathematical sets符號:

Server = Client1 ∪ Client2 ∪ ... ∪ ClientN 

其中,在一般情況下,任何記錄可能不是唯一到某個客戶:

ClientX ∩ ClientY ≠ 0, ∀ X,Y ∈ [1,N] 

這裏是一些假設:

  • 客戶端創建一個記錄。記錄的ID不能在客戶端上設置,因爲它可能與存儲在服務器上的記錄衝突。因此,需要將新創建的記錄提交給服務器 - >接收id - >在localStorage中創建記錄。

  • 記錄在服務器上更新,因此localStorage和服務器中的數據不同步。只有服務器知道,這樣的架構需要實現按鍵架構(?)

你會用2個店(一個用於本地存儲,一個REST),並同步在它們之間,或使用混合索引資料/ REST適配器並在適配器內寫入同步代碼?

你能看到任何避免實現推送(Web Sockets,...)的方法嗎?

+0

本文提供了一些見解:http://engineering.linkedin.com/mobile/linkedin-ipad-using-local-storage-snappy-mobile-apps –

回答

7

您提出的問題無法在幾段中回答,或者只是簡單回答。不過,這裏是我的嘗試......

首先,你已經通過與做法困難號碼:

  1. 客戶端必須始終網絡連接到創建的數據以及從服務器接收的鑰匙。
  2. 如果您確實創建了不同的商店(localstorage & REST),則所有需要數據的應用程序代碼都必須在兩個商店中查找。這顯着增加了應用程序的每個部分的複雜性。
  3. 創建行後,如果要創建子行,則必須等待服務器返回主鍵,然後才能將其作爲子行中的外鍵引用。對於任何中等複雜的數據結構,這成爲一個沉重的負擔。
  4. 服務器關閉時,所有客戶端都無法創建數據。

這是我的方法。它使用SequelSphereDB,但大多數概念可以在其他客戶端數據管理系統中重複使用。

第一:對主鍵使用UUID。

大多數客戶端數據管理系統應提供生成通用唯一ID的方式。SequelSphere只需使用SQL函數即可完成它:UUID()。通過將UUID作爲每行的主鍵,可以隨時在任何客戶端上生成主鍵,而無需與服務器聯繫,並且仍然保證ID是唯一的。這也因此允許應用程序以「脫機」模式工作,而不需要在運行時連接到服務器。這也使得服務器不能將所有客戶端關閉。

SECOND:使用一組鏡像服務器的表。

這比其他任何事情都更需要簡單性。這也是接下來兩項基本原則的要求。

THIRD:對於小數據集的向下同步,從服務器完全刷新客戶端數據是更可取的。

只要有可能,就從服務器執行客戶端數據的完整刷新。這是一個更簡單的範例,並且導致內部數據完整性問題更少。主要缺點是傳輸中的數據大小。

第四:對於大型數據集的下行同步,進行「交易」更新

這是我的做法變得有點複雜。如果數據集太大,並且只要求更改的行同步,則必須根據「事務」找到同步它們的方法。即:插入/更新/刪除按服務器上執行的順序進行插入/更新/刪除,以提供用於在客戶機上執行相同操作的簡單腳本。

最好在服務器上有一張表格,記錄要同步到設備的交易。如果這不可行,那麼通常可以在服務器上使用行上的時間戳記錄訂單,並讓客戶機要求自特定時間戳以來的所有更改。大負面影響:您需要通過「邏輯」刪除或通過在自己的表中跟蹤刪除行來跟蹤刪除的行。即使如此,將服務器的複雜性隔離開來,最好將其分散到所有客戶端。

第五:對於向上的同步,用「交易」的更新

這是SequelSphereDB真正的亮點:它會跟蹤你所有的插入,更新和刪除對錶進行,然後在同步時間將它們提供給您。它甚至可以跨瀏覽器重新啓動,因爲它將信息保存在localstorage/indexeddb中。它甚至可以適當地處理提交和回滾。客戶端應用程序可以像平常一樣與數據進行交互,而不必考慮記錄更改,然後使用SequelSphereDB的「更改跟蹤器」在同步時重播更改。

如果您的未使用 SequelSphere(應該是),則在客戶端上保留一個單獨的表以記錄客戶端執行的所有插入,更新和刪除操作。每當客戶端應用程序插入/更新/刪除行時,在「事務」表中複製該行。在向上同步時,發送這些。在服務器上,只需按照相同的順序執行相同的步驟即可複製客戶端上的數據。

同樣重要:始終在從服務器完全刷新客戶端表之前執行向上同步。:)

結論

我建議在儘可能多的地方儘量在複雜性去爲簡單。對主鍵使用UUID對此非常有幫助。使用某種「更改跟蹤器」也非常有用。使用像SequelSphereDB這樣的工具來跟蹤你的變化是最有用的,但這種方法不是必須的。

完整披露:我與公司SequelSphere密切相關,但該產品真的不是實施上述方法所必需的。

+0

謝謝約翰,偉大的見解。我開始實施一個原型,並且(或多或少)得出與您相同的結論。但是你更好地證明了他們:)但是,我不確定是否有必要記錄客戶端記錄的每個更改。不記錄更改**無記憶**?在那裏,你只需要知道記錄的最後狀態。我所做的是在客戶端創建一個'unsynced'表,並存儲所有已更改但尚未提交給服務器的記錄。一旦記錄被提交併與服務器同步後,它將從'unsynced'中移除。這有什麼缺點嗎? –

+0

事實上,在客戶身上創建ID是最好的選擇。一個缺點是JavaScript不能生成真正全球唯一的ID,如http://stackoverflow.com/a/105074/359104中所指出的那樣。但是,當然,這可以通過讓服務器驗證ID並立即返回任何更改的ID來超越。 –

+1

關於無記憶變化:這一切都取決於數據。有時創建子行需要父行具有特定的值。或者換句話說:在一組複雜的對象中維護引用完整性(RI)的最簡單方法就是「重放」客戶端上發生的插入,更新和刪除操作。通常,這是非常少的額外數據和工作,並且它具有簡單性的好處。確定更改的行要比記錄發生的更改困難得多。你有一個表或更改聽起來不錯。 –

相關問題