为实体生成唯一 ID

Generate a Unique ID for an entity

我正在从事 Lagom 项目,其中一项要求是唯一标识每个用户的文档。

文档有一个 ID,我应该在每次用户添加文档时生成它。

我的思路很简单,保证ID的唯一性:

我已经实现了 DocumentEventProcessor extends ReadSideProcessor<DocumentEvent>DocumentRepository 能够查询数据库。

我的问题是如何编写迭代(可能递归)查询数据库直到新的随机 ID returns 的函数。

为什么不使用 while 循环?

SaveDocumentWithNewId(){
//what pseudocode. 
String newRandomId = null;
while(result.size() != 0 )
newRandomId = GenerateRandomID();
ArrayList result= queryToDatabase(newRandomId);
}

document.setId(newRandomId );
}

您不应该使用读取端(即您的数据库)来保证 ID 的唯一性。在 Lagom(以及任何基于 CQRS 的系统,就此而言)中,读取端将始终只是最终一致的。因此,您最终可能会遇到这样的情况:两个节点生成相同的 ID,而数据库会告诉这两个节点它不存在,因为它还没有赶上。

您需要做的是确保您可以区分新创建的、未使用的 PersistentEntity 和已经有相关文档的文件。然后使用 PersistentEntityRegistry 为新生成的密钥获取 PersistentEntity。如果该实体已经存在,则生成一个新密钥。如果没有,您有钥匙。

算法 - 生成新 ID,直到找到未使用的 ID - 保持不变,只需确保使用 PersistentEntityRegistry 检查唯一性,而不是读取端。

通过搜索数据库检查生成的 ID 是否唯一是一个昂贵的过程。我建议您创建自己的 UUID(如 GUID),它应该 在系统中是唯一的 并且也基于要求(即 7个字符长)。

您可以创建自己的 ID,方法是获取系统的 inetAddress 并附加一个随机数,然后从中生成消息摘要,然后根据您的要求,您可以 trim 出 7 个字符从中。

通过这样做,您将在整个系统中拥有唯一的 ID 并满足您的要求。

供参考click here

也许你可以使用以下方法:

假设:
- 分布式系统,
- 7 个字符长的 ID,
- 您可以为每个节点分配一个唯一值 - hostId(可能是主机 IP 的最后一位数字?)

做什么:
- 每个节点都有一个 Singleton,它将生成 ID,
- 通过连接 hostId 和以毫秒为单位的当前时间来计算 uniqueNumericID(您应该存储上次使用的时间戳,以防万一您每毫秒需要多个 ID,只需将最后一个值加 1 直到最后一个时间戳 >= 当前时间戳)。
- 将此数值(十进制)转换为基数为 62 的数字(使用字符 '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' 并循环计算(其余)值的模数,使用模数作为字符的索引)。

您的 7 个字符长 ID 中 space 应该绰绰有余。