数据库条目的高效唯一密钥生成

Luk*_*lis 7 database key unique mongodb

我目前正在开发一个注册系统原型.它非常简单,基本上只是一个.NET表单,可以写入MongoDB.

我坚持的是为每个用户生成唯一ID /密钥的有效方法.这些ID必须是人类友好的,所以像7字符长的字母数字字符串,例如A1B2C3X.

到目前为止我看到的解决方案只是使用一个简单的函数来生成随机字符串,然后检查数据库以查看它是否是唯一的(如果不重复,直到找到一个唯一的).随着数据库条目数量的增加,这当然会变得越来越计算.

我的想法是预先计算唯一的id集并将其存储在另一个数据库中.然后当我需要在用户数据库中添加一个新条目时,我可以从我的id数据库中"弹出"一个id(在常数时间内),并且知道它不存在于用户数据库中而不需要搜索它.

我敢肯定以前有人必须做过这样的事情.有没有更好的办法?我不知道为什么我为此苦苦挣扎.非常感谢您的意见.

The*_*heo 11

在应用程序中生成随机字符串并检查它是否唯一不是一个糟糕的解决方案.不要担心它效率低下,它不是 - 并且绝对不能与其他选择进行比较.它肯定比运行db.user.count()或保留具有预先计算ID的单独表更快.你只需要做对.

首先,创建新用户的频率如何?可能不经常与其他事物相比,所以整个效率讨论真的没有实际意义.其次,有7个字符AZ,0-9表示36 ^ 7或大约780亿.至少可以说,在你开始看到碰撞之前还需要一段时间.

如果您这样做,除非发生碰撞(这种情况极不可能),否则不会产生任何性能损失:

  • 生成唯一的用户ID
  • 使用用户ID作为值插入用户对象 _id
  • 检查重复的键错误(如何执行此操作取决于语言和驱动程序,但可能涉及运行getLastError命令).
  • 在重复键错误上,通过生成新用户ID重新开始

这样在发生碰撞时只会有额外的工作(而且我真的非常想强调这将是多么不可思议的事情).

还有另一种生成唯一用户ID的方法:获取当前的UNIX时间戳(下至第二个),附加主机名的哈希值,然后附加进程ID,最后是计数器的当前值.这实际上是Mongo的ObjectId生成方式,并保证每个进程每秒可以生成尽可能多的对象,作为计数器的最大值(Mongo中的3个字节,即1600万个).如果您对详细信息感兴趣,请参阅ObjectId上的文档:http://www.mongodb.org/display/DOCS/Object+IDs

它具有以下属性:您的用户ID将按创建顺序自然排序,但它的长度为12个字节,因此比您的7个字符长一点.您可以使用相同的方法并跳过主机名/ pid,并将计数器(如果您愿意也可以是一个随机数)缩短为两个字节,那么您将减少到6个字节,这可能会被挤压到大约9个字节字符AZ,0-9.