用于多平台应用程序的可排序UUID v1

时间:2017-06-04 16:26:06

标签: javascript uuid multiplatform timeuuid node-uuid

我们正在寻找一种解决方案,为在Web,iOS和Android上的客户端之间交换的消息/信号生成唯一ID,然后保留在后端。

  • 解决方案必须标准化

  • 可在多个平台上使用

  • 按创建时间排序,可由数据库索引

UUID v1具有这些属性,除了排序和索引需要重新排列字符串标识符的一小部分。

UUID文档解释了时间块的顺序是相反的(从毫秒开始)(link)。

  UUID                   = time-low "-" time-mid "-"
                           time-high-and-version "-"
                           clock-seq-and-reserved
                           clock-seq-low "-" node
  time-low               = 4hexOctet
  time-mid               = 2hexOctet
  time-high-and-version  = 2hexOctet
  clock-seq-and-reserved = hexOctet
  clock-seq-low          = hexOctet
  node                   = 6hexOctet

由于UUID表示,我们不能简单地通过ID的字符串表示对ID进行排序,我们必须使用比较函数。

const toSortableUUID = uuidV1 =>
  uuidV1.replace(/^(.{8})-(.{4})-(.{4})/, '$3-$2-$1');

const uuidCompare = (uuidV1A, uuidV1B) => {
  if (uuidV1A === uuidV1B) {
    return 0;
  }
  const a = toSortableUUID(uuidV1A);
  const b = toSortableUUID(uuidV1B);
  return a < b ? -1 : 1;
};

const sortedArrayOfUUIDV1 = arrayOfUUIDV1.concat().sort(uuidCompare);

您是否知道另一种不会出现此问题的标准化方法?

使用UUID v1是否正确,但在重新安排的客户端之间进行交换,以便客户端可以按字符串表示排序,而不必每次都使用比较函数进行排序?

实时测试:https://codesandbox.io/s/q5oRxgnp

2 个答案:

答案 0 :(得分:2)

如果您重新排列UUID的位,则不再具有UUID。

另请注意,UUID标准的目的之一是允许混合不同版本的UUID的值。换句话说,通常您不应该假设您的UUID完全是一个版本。

UUID从未打算被撕裂,永远不会被视为容器。聪明的程序员如果想要这样做,那么聪明就是为了自己的利益。

然而,有些人确实改变了他们的UUID的结构或内容。我不推荐。

相反,我建议您确定并区分您的疑虑。

  • 标识符
    如果您需要在不与中央服务器协调的情况下跨时间和空间唯一标识您的实体,请使用适当的UUID。
  • 排序
    如果想要排序,则为排序值添加另一个字段。例如,如果要按时间顺序排序,请在数据库或数据接收器支持时存储时间戳值。如果不支持,请以标准ISO 8601格式存储UTC的日期时间值的文本表示。这种格式是明智地设计的,因此当按字母顺序排序时,它也是按时间顺序排列的。
  

2017-01-23T01:23:45.123Z

答案 1 :(得分:0)

主要回答是有点误导,使我误入歧途,所以我想在这里澄清一些事情。

  1. 排序-不建议重新排列UUID,但这并不意味着您不能按值排序。 Cassandra做到了,这是完全有效的。他们基本上使用与OP建议的方法相同的方法,但仅用作排序功能。
  2. 重新排列-如果您要构建一个完全控制的系统,则不建议重新排列UUID(尽管不建议这样做)仍然可以正常工作并且完全唯一。它可能不是通用唯一的,但假设您统一执行 ,在您的系统中它将是唯一的。

定义自定义排序功能

如上所述,Cassandra已经定义了用于对UUID进行排序的内置排序函数。如果有能力,您可以在其他系统中执行相同的操作,但是作为一个规范的Javascript示例,鉴于以下UUI,您可以像这样进行排序:

// Rearrange, only used for the purpose of sorting
const rearrangeId = uuid => {
  let [low, mid, hiAndVersion] = uuid.split('-')

  return [hiAndVersion, mid, low].join('')
}

// Sorting, using our rearrange function
uuids.sort((id1, id2) => {
  let rearranged1 = rearrangeId(id1)
  let rearranged2 = rearrangeId(id2)

  if (rearranged1 > rearranged2) {
    return 1
  }

  return -1
}

希望这对某人有帮助!