开发者

Is there a way to retroactively create time/node based UUID in PHP?

开发者 https://www.devze.com 2023-01-17 14:54 出处:网络
Most time-based (type 1) UUIDs are created using the current time. I\'m migrating a MySQL database to cassandra and would like to create timebased UUIDs for archived items. Can someone provide an exam

Most time-based (type 1) UUIDs are created using the current time. I'm migrating a MySQL database to cassandra and would like to create timebased UUIDs for archived items. Can someone provide an example of how type-1 UUIDs are created using past tim开发者_如何学Ce periods?


All uuids version 1 are a combination of node identifier (MAC address), timestamp and a random seed.

Yes its possible. The process is reversible.

From RFC4122 about the timestamp part of UUID version 1 (section 4.1.4):

"For UUID version 1, this is represented by Coordinated Universal Time (UTC) as a count of 100-nanosecond intervals since 00:00:00.00, 15 October 1582 (the date of Gregorian reform to the Christian calendar)."

Basic algorithm (section 4.2.1) for creating time base UUID (uuid version 1)


This should be the proper way to create UUIDs based on the past time in MySQL, but database reports duplicates:

UPDATE table
SET uuid = CONCAT(
  SUBSTRING(LOWER(HEX((CAST( 1000*created_timestamp AS UNSIGNED INTEGER) + (141427 * 24 * 60 * 60 * 1000)) * 1000 * 10)), 8, 8),
  '-',
  SUBSTRING(LOWER(HEX((CAST( 1000*created_timestamp AS UNSIGNED INTEGER) + (141427 * 24 * 60 * 60 * 1000)) * 1000 * 10)), 4, 4),
  '-',
  SUBSTRING(UUID(), 15, 1),
  SUBSTRING(LOWER(HEX((CAST(1000*created_timestamp AS UNSIGNED INTEGER) + (141427 * 24 * 60 * 60 * 1000)) * 1000 * 10)), 1, 3),
  '-',
  SUBSTRING(UUID(), 20, 17))

When altering first 5 chars instead of 8 chars it seems to work fine:

UPDATE table
SET uuid = CONCAT(
  SUBSTRING(LOWER(HEX((CAST( 1000*created_timestamp AS UNSIGNED INTEGER) + (141427 * 24 * 60 * 60 * 1000)) * 1000 * 10)), 8, 5),
  SUBSTRING(UUID(), 6, 3),
  '-',
  SUBSTRING(LOWER(HEX((CAST( 1000*created_timestamp AS UNSIGNED INTEGER) + (141427 * 24 * 60 * 60 * 1000)) * 1000 * 10)), 4, 4),
  '-',
  SUBSTRING(UUID(), 15, 1),
  SUBSTRING(LOWER(HEX((CAST( 1000*created_timestamp AS UNSIGNED INTEGER) + (141427 * 24 * 60 * 60 * 1000)) * 1000 * 10)), 1, 3),
  '-',
  SUBSTRING(UUID(), 20, 17))

To check timestamp of UUIDs you can use:

SELECT FROM_UNIXTIME(
        (CONV(
            CONCAT(
                SUBSTRING(uuid, 16, 3),
                SUBSTRING(uuid, 10, 4),
                SUBSTRING(uuid, 1, 8)
            ), 16, 10)
            DIV 10 DIV 1000 DIV 1000
        )
        -
        (141427 * 24 * 60 * 60)
    ) AS uuid_timestamp
FROM table;
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号