3

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

  • 解决方案必须标准化

  • 可在多个平台上使用

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

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

UUID 文档解释了时间块的顺序是颠倒的(从毫秒开始)(链接)。

  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

4

2 回答 2

4

如果您重新排列 UUID 的位您将不再拥有 UUID。

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

UUID 从来没有打算被撕裂,从来没有被视为一个容器。想到这样做的聪明的程序员聪明了。

然而,有些人确实改变了他们的 UUID 的结构或内容。我不建议这样做。

相反,我建议您识别并区分您的担忧。

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

2017-01-23T01:23:45.123Z

于 2017-06-04T16:46:28.867 回答
0

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

  1. 排序- 不建议重新排列 UUID,但这并不意味着您不能按值排序。Cassandra这样做了,而且它完全有效。他们基本上使用与 OP 建议的方法相同的方法,但仅作为排序功能。
  2. 重新排列- 如果您正在构建一个完全由您控制的系统,那么重新排列 UUID,虽然不推荐,但仍然可以正常工作并且是完全独特的。它可能不是普遍唯一的,但假设您统一执行此操作,它将在您的系统中是唯一的。

定义自定义排序函数

如上所述,Cassandra 已经定义了对 UUID 进行排序的内置排序函数。如果你有能力,你可以在其他系统中做同样的事情,但作为一个规范的 Javascript 示例,给定以下 UUId,你可以这样排序:

// 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
}

希望这对某人有帮助!

于 2020-06-29T13:30:34.047 回答