猿问

我可以将 AllocateID 用作“字符串”吗?数据存储

我需要为数据存储中的每个实体分配一个唯一标识符。我找到了AllocateIDs,但问题是它生成整数,我使用字符串作为键。将整数转换为字符串是否安全或存在冲突风险(即数据存储返回我当前用作字符串键的相同整数)。?


慕容708150
浏览 256回答 3
3回答

慕尼黑的夜晚无繁华

让我们先明确一些事情:实体键的标识符部分可以是一键名字符串或整数数字 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()函数可用于获取连续范围的intIDs,数据存储稍后将不会使用该范围intID自行生成s,因此您可以自由使用分配的范围intIDs 安全。这也意味着,如果有并发请求也试图保存新实体(在同一实例中或在其他实例中),intID如果标识符生成留给数据存储,它们也将永远不会使用这些s。回到你的问题您真的需要手动分配标识符吗?在大多数情况下,这仅在您已经拥有实体的唯一属性时才使用/需要,该属性对于 2 个不同的实体不能相同(例如,实体Person具有IdentityCardId每个人都已经独一无二的属性)。如果你有这样一个独特的属性,你可以使用本质上确保唯一性的属性。如果您没有这样的属性,那么您首先不应该使用手动标识符分配,您可以只使用/依赖intID数据存储的自动分配。请注意,您可以拥有相同类型的不同实体的混合标识符(例如,您可以拥有一个PersonwithintID和另一个Personwith name)。如上所述,intIDs 和names 是不同的。所以AllocateIDs()不会name仅仅因为name包含有效数字而考虑带有标识符的实体。从数据存储中,您无法获得“分配”name标识符(类似于 to AllocateIDs()allocation intIDs)的帮助,因此它必须是应用程序逻辑以确保分配name的唯一性,否则您最终将“覆盖”/替换现有实体。

慕码人8056858

您可以通过在 id 前面加上您知道从未用于密钥的任何字符串作为前缀来避免任何冲突的可能性。例如:String key = "id" + entity.getKey().getId();只有当您为字符串键使用整数序列时,所有这些才是必要的。

呼唤远方

让数据存储为您生成字符串键的方法是使用NewIncompleteKey.ikey := datastore.NewIncompleteKey(ctx, "Thing", nil)key, _ := datastore.Put(ctx, ikey, nil) // TODO: check the errorfmt.Println(key.Encode()) // randomly-generated string key然后从字符串键取回它......ks := req.FormValue("key") // e.g., from an HTTP request parameterkey, _ := datastore.DecodeKey(ks) // TODO: check the errorvar t Thing_ = datastore.Get(ctx, key, &t) // TODO: check the error
随时随地看视频慕课网APP

相关分类

Go
我要回答