简体   繁体   English

为实体生成唯一ID

[英]Generate a Unique ID for an entity

I'm working on Lagom project and one of the requirement is to uniquely identify each user's document. 我正在从事Lagom项目,其中一项要求是唯一标识每个用户的文档。

A document has an id that I should generate each time a user adds a document. 文档具有一个ID,每次用户添加文档时我应该生成一个ID。

My idea is simple to guarantee the unicity of the ID: 我的想法很简单,可以保证ID的唯一性:

  • generate a random string ID (NOT UUID) 产生随机字串ID(NOT UUID)
  • query the database for the generated ID 在数据库中查询生成的ID
  • IF query returns 0 hits THEN the ID is unique and I should return it to the caller 如果查询返回0次匹配,则ID是唯一的,我应该将其返回给调用方
  • IF query returns 1 hit THEN repeat all steps. 如果查询返回1次命中,则重复所有步骤。

I've implemented the DocumentEventProcessor extends ReadSideProcessor<DocumentEvent> and DocumentRepository to be able to query the database. 我已经实现了DocumentEventProcessor extends ReadSideProcessor<DocumentEvent>DocumentRepository以便能够查询数据库。

My problem is how to write the function that iteratively (recursively maybe) query the database until new random ID returns. 我的问题是如何编写迭代地(递归地)查询数据库直到返回新的随机ID的函数。

Why not use a while loop? 为什么不使用while循环?

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

document.setId(newRandomId );
}

You should not use the read side (ie your database) to guarantee the uniqueness of ids. 您不应使用读取端(即数据库)来保证ID的唯一性。 In Lagom (and any CQRS based system, for that matter), the read side will always be only eventually consistent. 在Lagom(以及与此相关的任何基于CQRS的系统)中,读取端始终只会最终保持一致。 So you could end up in a situation where two nodes generate the same id and the database will tell both that it doesn't exist, because it hasn't caught up yet. 因此,您可能会遇到以下情况:两个节点生成相同的ID,并且数据库会告知这两个ID不存在,因为尚未被捕获。

What you need to do instead is make sure you can distinguish between a newly created, unused PersistentEntity , and one that already has a document associated with it. 相反,您需要做的是确保可以区分一个新创建的,未使用的PersistentEntity和一个已经与之关联的文档。 Then you use the PersistentEntityRegistry to get the PersistentEntity for your newly generated key. 然后,使用PersistentEntityRegistry获取新生成的密钥的PersistentEntity If the entity already existed, generate a new key. 如果该实体已经存在,请生成一个新密钥。 If not, you have your key. 如果没有,则您拥有密钥。

The algorithm - generate new IDs until you found an unused one - remains the same, just make sure you use the PersistentEntityRegistry to check for uniqueness, not the read side. 该算法-生成新的ID,直到找到未使用的ID-保持不变,只需确保使用PersistentEntityRegistry来检查唯一性,而不是读取端。

It's a costly process to check whether an ID generated is unique by searching the database. 通过搜索数据库来检查生成的ID是否唯一,这是一个昂贵的过程 I will suggest you create your own UUID(Like a GUID) which should be unique across systems and which is also based on the requirement(ie 7 characters long). 我建议您创建自己的UUID(如GUID) ,该UUID 在整个系统中应该是唯一的,并且还基于要求(即7个字符长)。

You may create your own ID by taking the inetAddress of the system and attaching a random number to it and then generating a message digest out of it and then according to your requirement you can trim out 7 characters from it. 您可以通过获取系统的inetAddress并为它附加一个随机数,然后从中生成一个消息摘要来创建自己的ID,然后根据需要从中裁剪出7个字符。

By doing so you will have unique ids across the system as well as fulfill your requirement. 这样,您将在整个系统中拥有唯一的ID,并满足您的要求。

For reference click here 供参考, 请点击这里

Maybe you may use the following approach: 也许您可以使用以下方法:

assumptions: 假设:
- distributed system, -分布式系统,
- 7 characters long ID, -7个字符长的ID,
- you can assign each node a unique value - hostId (maybe last digits from your host IP?) -您可以为每个节点分配一个唯一值-hostId(也许是主机IP的最后几位?)

what to do: 该怎么办:
- have a per node Singleton which will generate the ID, -每个节点都有Singleton来生成ID,
- calculate uniqueNumericID by concatenating the hostId and the current time in millis (you should store last used timestamp, in case you need more than one ID per millisecond, just add one to the last value until last timestamp >= current timestamp). -通过连接hostId和当前时间(以毫秒为单位)来计算uniqueNumericID(您应该存储上次使用的时间戳,以防万一毫秒需要多个ID,请在最后一个值之前加上一个,直到最后一个时间戳> =当前时间戳)。
- convert this numeric value (decimal) to the number with base say 62 (use characters '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' and recurrently calculate modulo of the (rest of the) value, use the modulo as index of the character). -将此数字值(十进制)转换为基数为62的数字(使用字符'0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',并反复计算(其余)值的模数,使用模数作为字符的索引)。

There should be more than enough space in your 7 characters long ID. 您的7个字符长的ID中应该有足够的空间。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM