想在普通 id 之外,再加一个 uuid 的字段。 刚 google 了一下,好像有三种方法,
@seller.user_info_token = loop do
token = SecureRandom.urlsafe_base64
break token unless User.exists?(user_info_token: token)
end
@seller.user_info_token = SecureRandom.uuid
3.Rails 自带,API 文档,有 uuid_from_hash, uuid_v3, uuid_v4, uuid_v5。 网上关于 RAILS 自带的教程,说的都是用 postgres, 而且好像都是用 uuid 做主键,但我用 mysql 了,还是用普通 id 做主键,也一样?
恩,还没明白我这种场景应该是用什么样的方案? 你们都怎么做的?
还是选择了用 gem:uuidtools
具体实现,在 model 里
before_create do
self.some_other_id = UUIDTools::UUID.timestamp_create().to_s
end
谢谢各位:)
当你非常强调 unique 但是又没有很好的 Unique IDentifier 的时候,那么 uuid gem 是个不错的选择。 如果我没记错它会用到你的 MAC 地址 和 其它内容 一起作为 Unique IDentifier。所以你基本可以认为在不同的机器任何时刻一定 会生成不同的 uuid!
下载量难道不是检验一个 gem 好不好的最直接标准么?
一般如果有 gem 我就会选择用 gem,因为我总觉得我水平很菜,图样图森破,也许很多坑我并没有注意到,高手写得肯定比我好……
比如我刚才看到另一个代码,它会检测一下是否有重复的,我就想,哎呀,我可没有想到还有重复的可能,真够谨慎的……
@seller.user_info_token = loop do
token = SecureRandom.urlsafe_base64
break token unless User.exists?(user_info_token: token)
end
@seller.user_info_token = SecureRandom.uuid
@nouse @rubyu2
楼主说的是它用的 mysql.
还有 @chairy11 我再给你解释一下 uuid 的应用场景吧,这里只举一个栗子 只针区别你说的那个 普通 id 的情况
假设你有 Document, Photo, Text 三个 model, 他们分别有 id 和 uuid
你对外想做一个抽象,当用户请求
“objects/识别码”返回相应对象(可能是 Document, Photo 或 Text)。
你用 id 时没办法做的,因为他有可能重。
而这种抽象用 uuid 做将是极好的。
我只是举了很多例子中的一种应用场景。只是想说明 uuid 和你数据库的 自增 id 并不完全是一样的,但有些场景还是可以混用。
恩,还没明白我这种场景应该是用什么样的方案?
比如 客户端 可以方便的 cache 服务器端返回的带有 UUID 的 json - 直接按 uuid 扔到比如 Redis 里面就行了
@poshboytl @chairy11 这种用算法生成唯一序列,在极端情况下也是有碰撞概率的,不过一般情况下都是够用的。我说的就是 @diguage 这种方式,用数据库的自增性和唯一性再加一些自定义规则来保证全局唯一性。
SecureRandom 生成的是 UUID v4, 不是真正的 unique, 利用随机数来保证碰撞概率很小。正如 wiki 所说,碰撞概率很小,可惜有个前提:
However, these probabilities only hold when the UUIDs are generated using sufficient entropy. Otherwise, the probability of duplicates could be significantly higher, since the statistical dispersion might be lower. Where unique identifiers are required for distributed applications, so that UUIDs do not clash even when data from many devices is merged, the randomness of the seeds and generators used on every device must be reliable for the life of the application. Where this is not feasible, RFC4122 recommends using a namespace variant instead.
uuid gem 产生的 uuid 是用 mac+timestamp+local sequence, 代码简单明了。twitter 当年的 snowflake 是同样的思路 https://blog.twitter.com/2010/announcing-snowflake
分布式场景下 uuid 是最方便的选择,sequence 很难,有兴趣可以 google。
数据库 pg/mysql/mongodb 都可自己生成 , pg/mongodb 有专门的 uuid 类型,占用存储空间少一半
但数据库其实往往用的 uuid-ossp, ruby 也有这个 gem, 不需要和数据库通信生成速度自然快很多
如果要保证全局唯一性,得自己来制定生成规则