您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息
免费发信息

请教一个生成唯一id的算法是否存在重复?

2024/4/20 1:04:48发布5次查看
在网上看到一段代码 生成唯一id,有人评论说php的这段代码 生成id时重复性比较大,请教一下大家的看法,
class idwork{ const debug = 1; static $workerid; static $twepoch = 1361775855078; static $sequence = 0; const workeridbits = 4; static $maxworkerid = 15; const sequencebits = 10; static $workeridshift = 10; static $timestampleftshift = 14; static $sequencemask = 1023; private static $lasttimestamp = -1; public function __construct($workid) { if ($workid > self::$maxworkerid || $workid timegen(); while ($timestamp timegen(); } return $timestamp; } public function nextid() { $timestamp = $this->timegen();//1452043798718 if (self::$lasttimestamp == $timestamp) { self::$sequence = self::$sequence + 1 & self::$sequencemask; if (self::$sequence == 0) { $timestamp = $this->tilnextmillis(self::$lasttimestamp); } } else { self::$sequence = 0; } if ($timestamp nextid(), php_eol;$test = new idwork(1);echo $test->nextid(), php_eol;echo $test->nextid(), php_eol;

可以通过本身的测试
但并发的时候呢?
令你的第一段代码为 idwork.php,则 $mch = curl_multi_init();for($i=0; $i 0 );
8015005880150059801500588015005980150058801500598015005880150059801500588015005980150058801500598015005880150059
显然是不能通过并发测试的
get_order_sn方法里面
date('ymdhis'),取到秒,重复的概率就比较小了
我给你一种方法,但是位数的问题就看你自己怎么调整了
有一种不限制数字长度的方法可以使用(可以看出年月日十分秒+随机数)(26位数字)
$order_sn = date('ymdhis').substr(time(),-5).substr(microtime(),2,5).rand(10,99);
优点:
1、不用操作数据库,性能较高。
2、较为直观,不难看出订单产生的大致时间
3、订单号重复的概率极小,只有程序在百万分之一秒内同时处理一个以上的生成订单号请求,而且同时生成的10-99的随机数也一样才会出现重复的订单号。
2016010612111453474171874820160106121114534741718783201601061211145347417187832016010612111453474171871920160106121114534741718730201601061211145347417187772016010612111453474171871320160106121114534741718782
依然不能通过并发测试
只有 com_create_guid 生成全局唯一标识符(guid)
可确切的保证在同一服务器中不会重复
多台服务器间是否会重复,没有测试不能确认
而 guid 是号称全球唯一的
只有 com_create_guid 生成全局唯一标识符(guid)
可确切的保证在同一服务器中不会重复
多台服务器间是否会重复,没有测试不能确认
而 guid 是号称全球唯一的
谢谢版主的热心回答,但是如果把这个作为订单号的话就太长了,如果以12位的纯数字作为订单号的话 怎么设置订单号才能尽可能的保证唯一性
只有 com_create_guid 生成全局唯一标识符(guid)
可确切的保证在同一服务器中不会重复
多台服务器间是否会重复,没有测试不能确认
而 guid 是号称全球唯一的
谢谢版主的热心回答,但是如果把这个作为订单号的话就太长了,如果以12位的纯数字作为订单号的话 怎么设置订单号才能尽可能的保证唯一性
时间+用户id+商品序号+随机数
echo uniqid(), php_eol;echo uniqid(), php_eol;

568c83e69c671568c83e69c671

function get_order_sn(){ mt_srand((double) microtime() * 1000000); return date('ymd') . str_pad(mt_rand(1, 99999), 4, '0', str_pad_left);}echo get_order_sn(), php_eol;echo get_order_sn(), php_eol;

201601063753201601063753

显然都不能通过本身的测试
$idwork = new idwork(1);echo $idwork->nextid(), php_eol;echo $idwork->nextid(), php_eol;$test = new idwork(1);echo $test->nextid(), php_eol;echo $test->nextid(), php_eol;

可以通过本身的测试
但并发的时候呢?
echo uniqid(), php_eol;echo uniqid(), php_eol;function get_order_sn(){ mt_srand((double) microtime() * 1000000); return date('ymd') . str_pad(mt_rand(1, 99999), 4, '0', str_pad_left);}echo get_order_sn(), php_eol;echo get_order_sn(), php_eol;
这两种生成的方式   本身无法测试通过 是通过什么方式测试的  是指循环输出吗?
只有 com_create_guid 生成全局唯一标识符(guid)
可确切的保证在同一服务器中不会重复
多台服务器间是否会重复,没有测试不能确认
而 guid 是号称全球唯一的
  谢谢版主的热心回答,但是如果把这个作为订单号的话就太长了,如果以12位的纯数字作为订单号的话  怎么设置订单号才能尽可能的保证唯一性
时间+用户id+商品序号+随机数 
这个方法是不错,但是不能保证生成的位数  这个订单号会随着用户的id的增长 越来越大
只有 com_create_guid 生成全局唯一标识符(guid)
可确切的保证在同一服务器中不会重复
多台服务器间是否会重复,没有测试不能确认
而 guid 是号称全球唯一的
  谢谢版主的热心回答,但是如果把这个作为订单号的话就太长了,如果以12位的纯数字作为订单号的话  怎么设置订单号才能尽可能的保证唯一性
时间+用户id+商品序号+随机数 
这个方法是不错,但是不能保证生成的位数  这个订单号会随着用户的id的增长 越来越大
本身你定长的数字 也是有上限的。。。  在一次运行中产生 2 个 id,至少应保证这两个 id 应是不同的
如果连这个都不能保证,那如何能保证两个请求得到的 id 是不同的呢?
你的 idwork 类可以保证在一次程序运行中不出现重复,但在多次运行中仍会出现重复
com_create_guid 确实很长,但正因为如此,才能保证唯一
从常理可知,要想得到一个不曾出现过的 id,那就要检查他不在已出现过的 id 序列之中
而这个 已出现过的 id 序列 要保存在一个公共的地方,还要防止共享冲突
所以最佳的选择是利用数据库的自增字段
   感谢大家的热心回答  又学到了很多知识
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录