当前位置:Gxlcms > PHP教程 > PHP如何生成唯一的数字ID

PHP如何生成唯一的数字ID

时间:2021-07-01 10:21:17 帮助过:35人阅读

PHP如何生成唯一的数字ID,注意是数字的,不要字符串的

回复内容:

PHP如何生成唯一的数字ID,注意是数字的,不要字符串的

楼主,你这个问题大了。

twitter,weibo等都是专门做了一个发号器来解决这个问题的。
twitter那一套东西,叫做snowflake,楼上已经有人指出过了。这玩意一共64bit,前41bit是以微妙的时间戳,10bit是机器护着说服务器id,最后12bit是seq序列累加计数器。
weibo的方法和twitter是很类似的,将id分割为n个段,每段采集一定的数据源,最后生成一个高度唯一的id。

flickr是用的一个叫做ticketserver的玩意,使用纯mysql来实现的。
create table ticket(
id bigint unsigned not null auto_increment primary key,
stag char(1) not null default '',
unique key stag(stag)
)engine=myisam;
先插入一条记录,然后再用replace去获取这个id。
replace into ticket(stag) values('a');
select last_insert_id();====>ID

然后是,UUID也是一个不错的选择,但是UUID生成的序列太长,而且mysql本身不具备原生支持(我假装楼主用的mysql),但楼主可以尝试把uuid当作binary(16)来保存效果会好些儿。但楼主说是纯数字,那就白搭了。

还有一种,是我群里听到的。就是提前生成一大坨可用的唯一的id,用的时候直接取然后del掉,这也是可行的,因为说这个方案的那个人是个大神。为什么提前生成呢,我觉得最主要一条就是预防高并发情况下,两个人得到的id是一样 ; 提前生成的话可以排队一个一个生成,确保唯一。当然,他们的生成策略是什么我就不太清楚了。楼主可以参考twitter的做法。

另有,mongodb自带的objectId也是一种高度唯一的序列,楼主可以利用Mongodb生成的直接拿过来用,但也要确保高并发情况下,两个人或者更多人得到同一个id,虽然概率很低。但楼主说是纯数字,那还是白搭。

如果楼主玩的单机,那就不用太纠结唯一id的问题,主键自增就可以做唯一id。太长远的问题,现在可以考虑,但不能过于拘泥。如果楼主是分布式,那就是要必须了要这个东西了。

base_convert(uniqid(), 16, 10);

可以

redis incr

推荐一个 我自己在用的唯一数字ID生成器

https://github.com/sschiau/Particle.php

Particle

Language: PHP

64bits int Time Based ID Generator

PHP implementation of Twitter Snowflake ID Generator

Uncoordinated

For high availability within and across data centers, machines generating ids should not have to coordinate with each other.

Solution

  • PHP (tested on version 5.5.3)

  • id (64 bits) is composed of:

    • time - 41 bits (millisecond precision w/ a custom epoch)

    • configured machine id - 10 bits - up to 512 machines

    • sequence number - 12 bits - up to 2048 random numbers

System Clock Dependency

You should use NTP to keep your system clock accurate.

How to use it

Generate Particle ID

Change const EPOCH in particle class to today epoch time w/ miliseconds (13 digits)

    $machineID = 1; // Machine ID (aka Server ID no)
    
    Particle::generateParticle($machineID);

Time from Particle ID (w/ milisecond precision)

    $particleID = '4611692470816737853';
    
    Particle::timeFromParticle($particleID);

楼主应该说明唯一ID用途和使用场景,数据库自增ID,还有PHP是弱类型的,数字和字符串数值类型是可以通用,相互转换的.

没办法的, 除非你记录生成过的数字, 否则即使随机函数,时间戳生成数字都会出现重复的。

twitter全局唯一ID生成服务:snowflake(https://github.com/twitter/snowflake)
引用:
http://www.oschina.net/p/snowflake
http://www.cppblog.com/tx7do/archive/2014/06/10/207248.html

uniqid is really good, why don't you use it ? just need convert to number , first answer is cool.

sorry I can't type Chinese, because it's disabled on chrome , I think it's a bug of segmentfault.com

应该先说明场景,单机唯一还是多久唯一,单次请求唯一还是多次请求唯一

时间戳加随机数字的组合,但是保险起见,最好生成之后还是需要到记录过的ID池验证一下

@magicgod i think you can @SegmentFault to solve your question

不太明白题主的意思,是用在什么场景呢?在数据库的话直接设置ID自增不就可以了吗?如果是数组的话,那就直接$i++咯

可以用时间戳

可以生成一个保证同一时空内不重复的uuid或者guid,这个开源的类有很多,自己也可以写,根据当前时间戳+随机因子.随机因子可包括当前的pc的mac地址和随机字符串和当前代码的行数等等,PHP内置的函数:
com_create_guid可以完成你的功能.如果你不满足,github上有许多开源的实现.

补充:1应该是要固定长度 2遇到字母转成数字或将随机引起用数字表示

有一个办法,用当前时间戳,纯数字

贴上我一段伪代码,我使用过的id生成器

 $id = substr(strtotime(date("Y-m-d", time())), 0, 2) . substr(strrev(microtime()), 0, 2) . substr(mt_rand(), 0, 5) . substr(rand(), 0, 2);

$sql = "SELECT id FROM table WHERE id=" . $id . " LIMIT 1";
$data mysql_query($sql);

思路大概是时间戳加上随机数拼凑,具体实现当然楼主根据需求再做修改
虽然根据计算基本可以得出唯一,但是不能确保,最好入库加唯一键,通过查询来保证唯一值

事先生成一个数字池,然后要用的时候从池子取出就行了
如果那个数字释放了,直接放回池子就可以了

这样的话,随机啥的都好解决

人气教程排行