mongo 的简短用户友好 ID [英] Short user-friendly ID for mongo

查看:25
本文介绍了mongo 的简短用户友好 ID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个实时股票交易系统,并希望为用户提供一种可读的、用户友好的方式来参考他们的订单.例如,ID 应该像 8 个字符一样长,并且只包含大写字符,例如Z9CFL8BA.出于显而易见的原因,id 在系统中必须是唯一的.

I am creating a real time stock trading system and would like to provider the user with a human readible, user friendly way to refer to their orders. For example the ID should be like 8 characters long and only contain upper case characters e.g. Z9CFL8BA. For obvious reasons the id needs to be unique in the system.

我使用 MongoDB 作为后端数据库,并评估了以下不符合我要求的项目.

I am using MongoDB as the backend database and have evaluated the following projects which do not meet my requirements.

hashids.org - 这看起来不错,但它生成的 ID 太长了:

hashids.org - this looks good but it generates ids which are too long:

var mongoId = '507f191e810c19729de860ea';
var id = hashids.encodeHex(mongoId);
console.log(id)

导致:1E6Y3Y4D7RGYHQ7Z3XVM4NNM

which results in: 1E6Y3Y4D7RGYHQ7Z3XVM4NNM

github.com/dylang/shortid - 这要求您指定一个 64 个字符的字母表,并且如上所述我只想使用大写字符.

github.com/dylang/shortid - this requires that you specify a 64 character alphabet, and as mentioned I only want to use uppercase characters.

我知道实现我所寻找的唯一方法很可能是生成满足我要求的随机代码,然后检查数据库是否存在冲突.如果是这种情况,在 nodejs/mongodb 环境中执行此操作的最有效方法是什么?

I understand that the only way to achieve what I am looking for may well be by generating random codes that meet my requirements and then checking the database for collisions. If this is the case, what would be the most efficient way to do this in a nodejs / mongodb environment?

推荐答案

我知道实现我所寻找的唯一方法很可能是生成满足我要求的随机代码,然后检查数据库是否存在冲突.如果是这种情况,在 nodejs/mongodb 环境中执行此操作的最有效方法是什么?

I understand that the only way to achieve what I am looking for may well be by generating random codes that meet my requirements and then checking the database for collisions. If this is the case, what would be the most efficient way to do this in a nodejs / mongodb environment?

根据您的描述,您使用 [0-9A-Z] 范围内的 8 个字符作为id".即 36⁸ 个组合(≈ 2.8211099E12).假设您的交易系统在中短期内不会变得非常流行,那么发生碰撞的可能性就会相当低.

Given your description, you use 8 chars in the range [0-9A-Z] as "id". That is 36⁸ combinations (≈ 2.8211099E12). Assuming your trading system does not gain insanely huge popularity in the short to mid term, the chances of collision are rather low.

所以你可以采取一种乐观的方法,用下面的代码行生成一个随机 id(正如@idbehold 在评论中所注意到的,请注意 Math.random 可能不是足够随机,因此可能会增加碰撞的机会 - 如果你这样做,也许你应该调查 更好的随机发生器 [1])

So you can take an optimistic approach, generating a random id with something along the lines of the code below (as noticed by @idbehold in a comment, be warn that Math.random is probably not random enough and so might increase the chances of collision -- if you go that way, maybe you should investigate a better random generator [1])

> rid = Math.floor(Math.random()*Math.pow(36, 8))
> rid.toString(36).toUpperCase()
30W13SW

然后,在该字段上使用适当的唯一索引,您只需循环,重新生成新的随机 ID,直到在尝试插入新事务时没有冲突.由于碰撞的机会相对较小,因此应该终止.而且大部分时间这将在第一次迭代时插入新文档,因为没有冲突.

Then, using a proper unique index on that field, you only have to loop, regenerating a new random ID until there is no collision when trying to insert a new transaction. As the chances of collision are relatively small, this should terminate. And most of the time this will insert the new document on first iteration as there was no collision.

如果我没猜错的话,假设有 100 亿笔交易,你第一轮碰撞的几率仍然只有 0.3%,第二轮有 0.001% 多一点

[1] 在节点上,您可能更喜欢使用 crypto.pseudoRandomBytes 来生成您的随机 ID.你可能会围绕它构建一些东西,也许:

[1] On node, you might prefer using crypto.pseudoRandomBytes to generate your random id. You might build something around that, maybe:

> b = crypto.pseudoRandomBytes(6)
<SlowBuffer d3 9a 19 fe 08 e2>
> rid = b.readUInt32BE(0)*65536 + b.readUInt16BE(4)
232658814503138
> rid.toString(36).substr(0,8).toUpperCase()
'2AGXZF2Z'

这篇关于mongo 的简短用户友好 ID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆