我有一个包含数千行的表,该表有一列guid. 这通常在代码中生成,并且工作正常。
但是,这一次执行了批量导入,并且不包含 UUID 值。我现在需要更新此表,以便它确实具有 UUID 值。
我遇到的问题是,当我在循环中执行以下操作时:
(select uuid())
Run Code Online (Sandbox Code Playgroud)
不够随意。这意味着在内部,机器(名称?)和时间戳用于生成 uuid,这最终导致数十万行接收超级相似的 UUID。
不幸的是,我无法在软件堆栈中生成它,所以我想知道是否有人对此有任何提示或好的解决方案。
编辑对于那些接近的投票:
在数千行(select uuid())的update命令中使用时,它依赖于机器(节点)和时间戳。因为成千上万的行在彼此的微秒内更新,这会在所有行中产生一个不幸的相似字符串,例如:
1a5e308e-5530-11e7-a853-932d273ec009
1a5e3160-5530-11e7-a853-932d273ec009
1a5e32a0-5530-11e7-a853-932d273ec009
Run Code Online (Sandbox Code Playgroud)
将是前 3 个 uuid 生成并应用于更新查询中的前 3 行。这是有问题的,因为这些 UUID 用于前端可见的连接字符串的大部分。因此,最终结果是这些变得可以猜测,因此代表了矢量攻击的可能角度。
我提出这个问题的目的是,是否有另一种方法来生成一个 16 个字符、128 个字节的字符串,它遵循与 a 相同的模式UUID,但从一次迭代到下一次迭代可能具有更多的唯一性。
我希望我在这个解释中已经足够清楚了。
该函数在MySQL中生成完全随机的UUID(使用MySQL 5.6测试)
select LOWER(CONCAT(
LPAD(HEX(ROUND(rand()*POW(2,32))), 8, '0'), '-',
LPAD(HEX(ROUND(rand()*POW(2,16))), 4, '0'), '-',
LPAD(HEX(ROUND(rand()*POW(2,16))), 4, '0'), '-',
LPAD(HEX(ROUND(rand()*POW(2,16))), 4, '0'), '-',
LPAD(HEX(ROUND(rand()*POW(2,48))), 12, '0')
))
Run Code Online (Sandbox Code Playgroud)
请注意,它不是 UUIDv4,因为它没有指示版本 4 或变体的位(请参阅维基百科上的 UUIDv4) - 相反,它是完全随机的(或者更准确地说,与 MySQL 的RAND()函数可以生成的随机性一样)