3 回答

TA貢獻1864條經驗 獲得超6個贊
讓我們先明確一些事情:
實體鍵的標識符部分可以是
一鍵名字符串
或整數數字 ID
但不能兩者兼而有之。所以當你保存一個實體時,它的鍵要么有一個string
名為name的ID要么(異或)一個int64
名為intID的ID 。
2 個可選的標識符字段是不同的:如果您有一個實體,name="1234"
它與 with 的實體不同intID=1234
。
當您在未明確指定name
或 的情況下保存新實體時intID
,數據存儲將為它分配一個新的唯一intID
標識符。數據存儲永遠不會string
name
自己分配 a 。string
name
如果您string
name
自己指定,則只能擁有帶有標識符的實體。
數據存儲知道intID
它自己生成的自動生成的s,并且永遠不會生成相同的intID
兩次(井行為)。但是,如果您intID
自己指定一個新實體,則在保存新實體時,您必須注意它的唯一性。這將需要首先檢查intID
您想要使用的是否尚未使用(例如通過首先查詢它以查看是否還沒有實體intID
),但即使這樣也不能100%保證到您最終實際保存時具有此功能的實體仍將不被使用。該AllocateIDs()
函數可用于獲取連續范圍的intID
s,數據存儲稍后將不會使用該范圍intID
自行生成s,因此您可以自由使用分配的范圍intID
s 安全。這也意味著,如果有并發請求也試圖保存新實體(在同一實例中或在其他實例中),intID
如果標識符生成留給數據存儲,它們也將永遠不會使用這些s。
回到你的問題
您真的需要手動分配標識符嗎?在大多數情況下,這僅在您已經擁有實體的唯一屬性時才使用/需要,該屬性對于 2 個不同的實體不能相同(例如,實體Person
具有IdentityCardId
每個人都已經獨一無二的屬性)。
如果你有這樣一個獨特的屬性,你可以使用本質上確保唯一性的屬性。如果您沒有這樣的屬性,那么您首先不應該使用手動標識符分配,您可以只使用/依賴intID
數據存儲的自動分配。
請注意,您可以擁有相同類型的不同實體的混合標識符(例如,您可以擁有一個Person
withintID
和另一個Person
with name
)。
如上所述,intID
s 和name
s 是不同的。所以AllocateIDs()
不會name
僅僅因為name
包含有效數字而考慮帶有標識符的實體。從數據存儲中,您無法獲得“分配”name
標識符(類似于 to AllocateIDs()
allocation intID
s)的幫助,因此它必須是應用程序邏輯以確保分配name
的唯一性,否則您最終將“覆蓋”/替換現有實體。

TA貢獻1803條經驗 獲得超6個贊
您可以通過在 id 前面加上您知道從未用于密鑰的任何字符串作為前綴來避免任何沖突的可能性。例如:
String key = "id" + entity.getKey().getId();
只有當您為字符串鍵使用整數序列時,所有這些才是必要的。

TA貢獻1856條經驗 獲得超11個贊
讓數據存儲為您生成字符串鍵的方法是使用NewIncompleteKey.
ikey := datastore.NewIncompleteKey(ctx, "Thing", nil)
key, _ := datastore.Put(ctx, ikey, nil) // TODO: check the error
fmt.Println(key.Encode()) // randomly-generated string key
然后從字符串鍵取回它......
ks := req.FormValue("key") // e.g., from an HTTP request parameter
key, _ := datastore.DecodeKey(ks) // TODO: check the error
var t Thing
_ = datastore.Get(ctx, key, &t) // TODO: check the error
- 3 回答
- 0 關注
- 286 瀏覽
添加回答
舉報