请教一个生成唯一id的算法是否存在重复?
在网上看到一段代码 生成唯一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 < 0) { throw new Exception('worker Id can\'t be greater than 15 or less than 0'); } self::$workerId = $workId; } public function timeGen() { //获得当前时间戳 $time = explode(' ', microtime()); $time2 = substr($time[0], 2, 3); $timestramp = $time[1] . $time2; return $time[1] . $time2; } public function tilNextMillis($lastTimestamp) { $timestamp = $this->timeGen(); while ($timestamp <= $lastTimestamp) { $timestamp = $this->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 < self::$lastTimestamp) { throw new Excwption('Clock moved backwards. Refusing to generate id for ' . (self::$lastTimestamp - $timestamp) . ' milliseconds'); } self::$lastTimestamp = $timestamp; $nextId = sprintf('%.0f', $timestamp) - sprintf('%.0f', self::$twepoch) | self::$workerId << self::$workerIdShift | self::$sequence; return $nextId; }}$Idwork = new Idwork(1);$a = $Idwork->nextId();
还有下面这个生成唯一id的方式
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();
这两种方式哪种更好一些,或者还有没有其它的方式在高并发的情况下生成唯一id不重复的方法
回复讨论(解决方案)
请使用PHP内置函数uniqid
参考: http://php.net/manual/zh/function.uniqid.php
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;
但并发的时候呢?
令你的第一段代码为 Idwork.php,则
$mch = curl_multi_init();for($i=0; $i<4; $i++) { $ch = curl_init('http://localhost/Idwork.php'); curl_multi_add_handle($mch, $ch);}$running = NULL;do { usleep ( 10000 ); curl_multi_exec ( $mch, $running );} while ( $running > 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 是号称全球唯一的
只有 com_create_guid 生成全局唯一标识符(GUID)
可确切的保证在同一服务器中不会重复
多台服务器间是否会重复,没有测试不能确认
而 GUID 是号称全球唯一的
时间+用户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 是号称全球唯一的
时间+用户id+商品序号+随机数
这个方法是不错,但是不能保证生成的位数 这个订单号会随着用户的id的增长 越来越大
只有 com_create_guid 生成全局唯一标识符(GUID)
可确切的保证在同一服务器中不会重复
多台服务器间是否会重复,没有测试不能确认
而 GUID 是号称全球唯一的
时间+用户id+商品序号+随机数
这个方法是不错,但是不能保证生成的位数 这个订单号会随着用户的id的增长 越来越大
本身你定长的数字 也是有上限的。。。
在一次运行中产生 2 个 id,至少应保证这两个 id 应是不同的
如果连这个都不能保证,那如何能保证两个请求得到的 id 是不同的呢?
你的 Idwork 类可以保证在一次程序运行中不出现重复,但在多次运行中仍会出现重复
com_create_guid 确实很长,但正因为如此,才能保证唯一
从常理可知,要想得到一个不曾出现过的 id,那就要检查他不在已出现过的 id 序列之中
而这个 已出现过的 id 序列 要保存在一个公共的地方,还要防止共享冲突
所以最佳的选择是利用数据库的自增字段
感谢大家的热心回答 又学到了很多知识

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Laravel은 직관적 인 플래시 방법을 사용하여 임시 세션 데이터 처리를 단순화합니다. 응용 프로그램에 간단한 메시지, 경고 또는 알림을 표시하는 데 적합합니다. 데이터는 기본적으로 후속 요청에만 지속됩니다. $ 요청-

PHP 클라이언트 URL (CURL) 확장자는 개발자를위한 강력한 도구이며 원격 서버 및 REST API와의 원활한 상호 작용을 가능하게합니다. PHP CURL은 존경받는 다중 프로모토콜 파일 전송 라이브러리 인 Libcurl을 활용하여 효율적인 execu를 용이하게합니다.

Alipay PHP ...

Laravel은 간결한 HTTP 응답 시뮬레이션 구문을 제공하여 HTTP 상호 작용 테스트를 단순화합니다. 이 접근법은 테스트 시뮬레이션을보다 직관적으로 만들면서 코드 중복성을 크게 줄입니다. 기본 구현은 다양한 응답 유형 단축키를 제공합니다. Illuminate \ support \ Facades \ http를 사용하십시오. http :: 가짜 ([ 'google.com'=> 'Hello World', 'github.com'=> [ 'foo'=> 'bar'], 'forge.laravel.com'=>

고객의 가장 긴급한 문제에 실시간 인스턴트 솔루션을 제공하고 싶습니까? 라이브 채팅을 통해 고객과 실시간 대화를 나누고 문제를 즉시 해결할 수 있습니다. 그것은 당신이 당신의 관습에 더 빠른 서비스를 제공 할 수 있도록합니다.

기사는 PHP 5.3에 도입 된 PHP의 LSB (Late STATIC BING)에 대해 논의하여 정적 방법의 런타임 해상도가보다 유연한 상속을 요구할 수있게한다. LSB의 실제 응용 프로그램 및 잠재적 성능

이 기사에서는 프레임 워크에 사용자 정의 기능 추가, 아키텍처 이해, 확장 지점 식별 및 통합 및 디버깅을위한 모범 사례에 중점을 둡니다.

기사는 입력 유효성 검사, 인증 및 정기 업데이트를 포함한 취약점을 방지하기 위해 프레임 워크의 필수 보안 기능을 논의합니다.
