在搜索SO和其他网站后,我未能提供确凿的证据证明Facebook,Twitter和Pinterest如何生成他们的ID。需要这样做的原因是为了避免网址冲突。转移到一个完全不同的ID将阻止这种情况,因为不会有数以万计的记录。
如果以Pinterest为例,前几位数与用户ID有关,最后6位左右的数字代表保存ID,可能是自动增量。
要创建类似的ID,但不是唯一的,我可以使用:base_convert(user_id.save_id, 16, 10)
。这里的问题是它不是唯一的,例如:base_convert(15.211, 16, 10)
与base_convert(152.11, 16, 10)
。这两个是一样的。只需合并两组唯一的数字仍然会产生重复的结果。将uniqid()
投入到混合中将基本上修复重复项,但这似乎不是一种很好的做法。
更新:Twitter似乎使用了这个:https://github.com/twitter/snowflake
有关生成唯一ID的建议,例如上述示例吗?
答案 0 :(得分:7)
假设您的ID都是数字。用字符A
分隔它们(因为它肯定不会出现在原始ID中),并从base-11到base-10进行基本转换。
对于您所做的示例,我们现在得到不同的结果:
echo base_convert("15A211", 11, 10); //247820
echo base_convert("152A11", 11, 10); //238140
答案 1 :(得分:3)
实际上,如果你查看(例如)朋友(在Facebook上)上的用户ID,你会注意到它们在所有用户之间是连续的,就像AUTO_INCREMENT数据库字段一样。然而,他们可能不会从1开始。例如,我的朋友列表有数百万的数字,然后突然跳到1万亿等等,所以我的猜测是auto_increment值被提升了 - 这可能会完成“隐藏”确切的用户数量。
无论如何,要生成唯一ID,只需使用该AUTO_INCREMENT字段顺序创建它们。 (可选)将初始值设置为高值。
答案 2 :(得分:3)
上面的Flickr评论非常有用。我们也使用分片。我们有一个bigint(int64)定位器字段。它是通过组合int(int32)数据库id和int(int32)标识字段生成的。
如果您知道数据库最大数量为int16(非常可能),则可以组合使用int16(smallint)数据库ID和int32(int)用户ID以及int16(smallint)操作ID。我不知道你申请的合理数字。但是为数据库ID保留一些部分,即使它只是tinyint,所以如果你添加更多数据库,你就知道你将来是安全的。