2012-05-14 78 views
2

開發中我有一個空的數據存儲。 在線我有一個擁有數百萬實體的數據存儲。數據存儲實體密鑰衝突

在開發數據存儲(本地)中,我放置了一個新實體(生成一個新密鑰)。 然後我導出實體並將其放入在線數據存儲區(使用本地生成的密鑰)。在本地生成的密鑰已經分配給在線數據存儲中的實體的風險是什麼?

或者,它會更簡單通過本地創建密鑰這樣避免相撞:

for (int i = 0; i < data.size(); i++) { 
    Key k = KeyFactory.createKey(kind, new Date() + i); 
    // continue to creating and inserting entities... 
} 

感謝。

回答

3

https://developers.google.com/appengine/docs/java/datastore/entities

而是使用自動鍵名稱字符串或生成數字ID 的,先進的應用程序可能有時希望手動分配 自己的數字ID,以他們所創造的實體。但請注意, 但沒有任何內容阻止數據存儲將 其中一個手動數字標識分配給另一個實體。 避免這種衝突的唯一方法是讓您的應用程序通過DatastoreService.allocateIds()或 AsyncDatastoreService.allocateIds()方法獲取ID爲 的塊。數據存儲區的自動ID 生成器將跟蹤已使用這些 方法分配的ID,並將避免將它們重複用於其他實體,因此您可以安全使用這些ID而不會發生衝突。

必須要麼產生所有數字鍵的手動(並以這樣的方式,他們將永遠不會發生碰撞),或者使用allocateIds()。除非您使用該功能,否則不能保證手動生成的任何內容不會與現有密鑰相沖突。生成的鍵ID不像每次增加1的關係數據庫中的自動增量字段。

+0

創建的,但我們在這裏討論的是將實體(因此創建密鑰)放在本地數據存儲中的開發模式,然後將它們導出到生產在線數據存儲區在我看來,在這種情況下防止衝突的唯一方法是使用某種時間相關的ID /名稱創建密鑰。 –

+0

只有當您以這種方式生成100%的實體鍵時(即,確切地說0放不帶ID),並且以這樣的時間分辨率來創建零重複將被創建時,這將僅工作。如果您已經有一個以普通方式創建的實體,它可能會失敗。 – mjibson

0

這取決於您在實體上擁有的ID的種類。如果它們是整數,則它們很小,並且很容易發生衝突。

我會建議只創建一個與Google默認使用的略有不同的關鍵格式。只要KeyFactory使用時鐘的完整精度(即不會在數秒內停止),上面的函數看起來應該工作。

+0

我從來沒有設置任何密鑰的任何ID。它們都是標準的,當我第一次放置實體時自動分配。在虛擬關係中,我使用KeyFactory.keyToString()。 –

+0

所有的實體都是使用'new Entity(kind)' –

0

當數據存儲生成密鑰時,ID爲整數。如果您使用字符串作爲ID生成密鑰,那麼它們將不會覆蓋現有的實體。

a.key.id() == 1 
b.key.id() == '1' 
a.key.id() != b.key.id() 
0

您應該提供一些關於您的用例的更多信息,以便任何人提出適當的解決方案。你可以爲實例的開發數據庫這樣就創建鍵:

KeyFactory.createKey(entity, "dev_" + UUID.randomUUID()) 

另一種選擇是創建一個小工具或應用程序,將在本地數據庫中檢索實體,然後將其發佈到開發數據庫。在線服務器獲取POST將創建一個新的實體並從客戶端除鍵分配所有屬性,從而讓GAE自動生成一個新的密鑰。然後可以將新密鑰發送回客戶端,作爲對POST操作的響應。

同樣,我不知道你以後是否想更新本地數據庫與在線重新同步,但如果是這樣,定義自己的密鑰的第一種方法將工作,因爲下一個同步將在線更新實體。