【发布时间】:2012-12-18 11:46:05
【问题描述】:
我需要获得基于时间的唯一 ID,它只包含数字,我想简单地使用这样的东西:
str_replace(".", "", microtime(true))
我会将此 id 用于许多事情,例如 cmets 发布,并且我预计流量会很高,所以我想知道与 microtime 函数发生冲突的可能性有多大?
也许有更好的方法来获取数字唯一 ID?请记住,它必须基于时间才能进行排序。
【问题讨论】:
我需要获得基于时间的唯一 ID,它只包含数字,我想简单地使用这样的东西:
str_replace(".", "", microtime(true))
我会将此 id 用于许多事情,例如 cmets 发布,并且我预计流量会很高,所以我想知道与 microtime 函数发生冲突的可能性有多大?
也许有更好的方法来获取数字唯一 ID?请记住,它必须基于时间才能进行排序。
【问题讨论】:
您可以使用它来获取 uniqid 但不是数字:
$id = uniqid(); //58aea16085f6b
使用它来将其转换为仅数字:
$id = hexdec( uniqid() ); //1560112880181100
如果它太长,使用它但可能会得到负数:
$id = crc32( uniqid() ); //-1551585806
如果你只需要正数,你可以这样做:
$id = abs( crc32( uniqid() ) ); //1551585806
【讨论】:
如果必须基于时间,您可以使用微时间。但我猜你是在数据库中存储东西,所以我的投票是primary key 列Id 和auto_increment,然后是第二列timestamp 类型和默认current time。
然后您可以按时间戳进行排序,并且即使在流量极高的情况下也可以拥有 100% 的唯一标识符。但是如果需要订购(所以不要在日期之间搜索),那么您就不需要根据时间来订购。
1、2、3、4 的顺序与 microtime 键的顺序相同,只是更大更远。
更新
如果它必须是唯一键并且不能从数据库中使用,请尝试以下操作。重复键的变化很小,可以忽略。
$key = microtime() + floor(rand()*10000);
【讨论】:
如果您需要使用纯基于时间的 ID,则需要确保避免冲突,因此 a) 在数据库中使用主键,然后 b) 使用递归检查以确保您的基于时间的 ID 尚未采取:
$id = getTimeId();
function getTimeId() {
// Generate microtime
// Query to ensure it does not exist
// Return microtime
}
我将把它留给你好先生,享受使其递归的乐趣。
【讨论】:
如果你必须避免基于时间的碰撞将不起作用。最终你会发生碰撞。为什么不使用带有信号量的计数器。
【讨论】: