Javascript 为Couchbase生成唯一的UInt32 ID

Javascript 为Couchbase生成唯一的UInt32 ID,javascript,node.js,couchbase,Javascript,Node.js,Couchbase,我正在寻找一种为nosql数据库生成唯一ID的方法。与关系数据库不同,它不知道行,这意味着没有最后一行可以从中递增 最常见的处理方法是使用UUID。但我的问题是我需要添加另一个ID(UUID除外),它需要: 独特的 无符号Int32 总数据可能达到5000万左右。那么,如何生成某种程度上的唯一uint32 ID UInt32值类型表示值范围为0到4294967295的无符号整数 仅在新用户注册时生成 为每个新用户提供3个Id 当前正在使用Couchbase服务器 这里有一个函数,每次调用它

我正在寻找一种为nosql数据库生成唯一ID的方法。与关系数据库不同,它不知道行,这意味着没有最后一行可以从中递增

最常见的处理方法是使用UUID。但我的问题是我需要添加另一个ID(UUID除外),它需要:

  • 独特的
  • 无符号Int32
总数据可能达到5000万左右。那么,如何生成某种程度上的唯一uint32 ID

UInt32值类型表示值范围为0到4294967295的无符号整数

  • 仅在新用户注册时生成
  • 为每个新用户提供3个Id
  • 当前正在使用Couchbase服务器
      这里有一个函数,每次调用它时都返回一个唯一的标识符。只要项目的数量不超过32位整数的范围就可以了,这似乎是给定所述要求的情况。(警告:一旦UID数组填满,将进入无限循环。您可能还需要创建某种重置函数,以清空数组,从而在必要时重置UID。)


      这个问题已经解决了——我建议在Couchbase中使用原子函数——这是生成唯一ID的常见模式

      每当调用
      incr()
      方法时,它都会按指定的值自动递增计数器,并返回旧值,因此如果两个客户端同时递增,则是安全的

      伪代码示例(我不是Node.JS专家!):


      有关完整的用法示例,请参阅参考,并参阅Couchbase Developer Guide中的部分。

      如果您将通过传递“user”作为键来调用此插入方法,则您的docId将自动递增为 用户0 用户1 用户2 等 请注意,couchbase将在bucket中显示一个额外的行,其中key作为meta id,next counter value作为doc value。若您使用类似select count(*)total from table的查询,请不要感到惊讶;因为它将比实际计数多显示一个,以避免使用where子句,从而使此行不会被计数

      public insert(data: any, key: string) {
        return new Promise((resolve, reject) => {
          let bucket = CouchbaseConnectionManager.getBucket(`${process.env.COUCHBASE_BUCKET}`)
          bucket.counter(key, 1, {initial:0}, (err:any, res:any)=>{
            if(err){
              this.responseHandler(err, res, reject, resolve);
            }
            const docId = key + "_" + res.value;
            bucket.insert(docId, data, (error:any, result:any) => {
              this.responseHandler(error, result, reject, resolve);
            });
          });
        });
      }
      

      多久生成一次?您可能可以从unix时代开始使用ms。。还有,CRC32?也许几分钟一次。有时它们可能同时发生,但不太可能。@PaulS.:应该是几秒钟?@PaulS。我可以使用CRC32用户名,对吗?由于用户名将是唯一的,并且该ID将提供给注册中的每个用户,问题是,每个新注册的用户应提供3个数字。刚刚意识到crc可以包含字母,所以它不会工作?@minitech看起来很有希望。你知道它是否适合我的用例吗?您可能希望将其添加为答案。我会接受的。谢谢。当应用程序重新启动时,这不会忘记ID吗?如果您将其从
      1>>0)更改为
      。另外,看起来像是
      uid
      最初应该是
      {}
      ,而不是
      []
      ;更新
      length
      在不准确的情况下是浪费时间的。@minitech我从
      1@majidarif改为几乎任何JavaScript解决方案都可以。然而,通过在应用程序启动时用ID预先填充数组很容易解决这个问题。如果在文档中增加一个计数器,则Dec似乎可以工作。跨文档如何,但我必须检查一下。我一回来就会回来,因为我还在工作。@Majidari如果你有一个作为计数器的文档-例如,对于userid,你可能有一个名为
      userid::count
      的文档,你可以使用
      incr()
      打开它来生成下一个userid.hmmm,我不会跟随。你能再解释一下吗?插入新文档时,是否应获取最后一次计数并递增?如果同时插入两个文档,这不是问题吗。如果他们得到相同的最后计数?从您更新的答案中,我看到它确实增加了计数文档。但是在下一个文档中插入下一个数字怎么样。我应该先递增计数器,然后获取数字,然后插入新文档吗?如果您查看我链接的完整示例,您会看到调用
      incr()
      会自动递增计数器并返回以前的值-因此,无论何时创建新用户,只要执行
      nextID=counter.incr();newKey=“prefix”+nextID
      或类似文件。
      // Once, at the beginning of time we init the counter:
      client.set("user::count", 0);
      ...
      // Then, whenever a new user is needed: 
      nextID = client.incr("user::count", 1); // increments counter and returns 'old' value.
      newKey = "user_" + nextID;
      client.add(newKey, value);
      
      public insert(data: any, key: string) {
        return new Promise((resolve, reject) => {
          let bucket = CouchbaseConnectionManager.getBucket(`${process.env.COUCHBASE_BUCKET}`)
          bucket.counter(key, 1, {initial:0}, (err:any, res:any)=>{
            if(err){
              this.responseHandler(err, res, reject, resolve);
            }
            const docId = key + "_" + res.value;
            bucket.insert(docId, data, (error:any, result:any) => {
              this.responseHandler(error, result, reject, resolve);
            });
          });
        });
      }