是时候使用NanoID取代UUID了
是时候使用NanoID取代UUID了


UUID是软件开发中最常用的通用标识符之一。然而,在过去的几年里,其他替代品挑战了它的存在。
其中,NanoID 是取代 UUID 的主要竞争对手之一。在介绍NanoID 之前我们先介绍一下UUID
UUID
UUID的定义
UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。
UUID是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的
UUID是基于当前时间、计数器(counter)和硬件标识(通常为无线网卡的MAC地址)等数据计算生成的
如此一来,每个人都可以创建不与其它人冲突的UUID,虽然 UUID 被复制的概率不为零,但它足够接近于零,可以忽略不计
UUID格式
总长度 36,由 32 个 16 进制字符和 4 个连字符组成。连字符仅用于增加可读性,实际的精度为
一个 16 进制字符为2^4=4bit,32 个则为32*4bit=128bit
00000000-0000-0000-0000-000000000000
UUID的版本
UUID具有多个版本,每个版本的算法不同,应用范围也不同。
版本1:
UUID 是根据日期时间和MAC地址生成;
48bit 主机的 Mac 地址
60bit 时间戳 (13-14bit 作为时间序列)
每个节点每秒钟可生成 1630 亿个,也就是说每毫秒 163 个
版本2:
UUID是根据标识符(通常是组或用户ID),日期时间和MAC地址生成;
48bit 主机的 Mac 地址
40bit 域名/ID
28bit 时间戳(6bit 作为时间序列)
允许一个节点存在 1 万亿个 域名/ID 对象,每个对象每 7 秒产生一个 UUID
版本3,版本5:
确定性UUID 通过散列(hashing)名字空间(namespace)标识符和名称生成;
版本3使用 MD5 作为散列算法,版本5使用 SHA1
SHA1比MD5更不容易碰撞
版本4:
UUID 使用随机性或伪随机性生成。
6bit 标记版本
122bit 随机数
每秒生成 10 亿个,大约需要 85 年才有重复的可能,所以在正常应用情形下这种碰撞概率可以忽略
因为时间戳和随机数的唯一性,版本1和版本4总是生成唯一的标识符。若希望对给定的一个字符串总是能生成相同的 UUID,使用版本3或版本5
UUID的碰撞问题
当多次生成相同的 UUID 并分配给不同的引用时,就会发生冲突。
版本1和版本2使用来自网卡的唯一 MAC 地址,生成的UUID几乎不可能发生冲突
基于哈希的版本3 和版本5,以及随机版本4,即使没有实现问题,也可能发生冲突,尽管概率很小,通常可以忽略。这个概率可以根据生日问题的分析精确计算。
例如,为了有 50% 的概率至少发生一次冲突,需要生成的随机版本 4 UUID 的数量为 2.71 *10次方,计算如下

这个数字相当于大约 85 年每秒产生 10 亿个 UUID ,每个 UUID 16 bytes/字节,包含这么多 UUID 的文件,大约 45 EB,比目前存在的最大数据库大很多倍,它们都在数百PB的数量级

在 103 万亿个版本 4 UUID 中找到重复的概率是十亿分之一
UUID版本选择
版本4- 首选
版本1 - 如果需要反向解析主机 Mac 地址
版本5 - 如果需要根据特定的值生成,而且在值不变的情况下生成的 UUID 不变。
可用于加密用户密码,比如我的密码是 123456,sha1 固定为7c4a8d09ca3762af61e59520943dc26494f8941b,所以一旦数据库数据泄露,很容易枚举出简单的密码原文。但使用 v5 算法后加入了特定的 namespace,会得到完全不同,且不具备普遍性的 UUID 串,这样就很难破解出密码原文了。
版本3 - 不推荐,用 版本5 替代
版本2 - 一般不会用到
UUID作为数据库的主键
UUID 通常用作唯一键的数据库表。
PostgreSQL 包含一个 UUID 数据类型,并且可以通过使用模块中的函数生成大多数版本的UUID。
MySQL 提供了一个 UUID 函数,它生成版本1的UUID。
当 UUID 用作主键时,版本3、4和5 UUID 的随机性以及 版本1和2 UUID 内的字段的排序可能会产生数据库位置或性能问题。
例如,2002年 Jimmy Nilsson 报告说,当用作主键的版本4 UUID 被修改为包含基于系统时间的非随机后缀时,Microsoft SQL Server 的性能显著提高。通过对版本 1 和 2 UUID 进行重新排序和编码以便时间戳在前,可以避免插入性能损失
NanoID
下面我将讨论 NanoID 的特点、它的优势以及它的局限性,以便让您更好地了解何时使用它。
NanoID介绍
Nano ID 与 UUID v4 (基于随机) 相当。它们在 ID 中有相似数量的随机位 (Nano ID 为126,UUID 为122),因此它们的冲突概率相似,要想有十亿分之一的重复机会, 必须产生103万亿个版本4的ID.
Nano ID 和 UUID v4之间有下面几点主要区别
-
Nano ID 使用更大的字母表,所以类似数量的随机位 被包装在21个符号中,而不是36个。
-
Nano ID 代码比uuid/v4包少4倍: 130字节而不是483字节.
-
由于内存分配的技巧,Nano ID 比 UUID 快 60%。
-
不可预测性,不使用不安全的 Math.random(), Nano ID 使用 Node.js 的 crypto 模块和浏览器的 Web Crypto API。这些模块使用不可预测的硬件随机生成器。
-
统一性,NanoID 在 ID 生成器的实现过程中使用了自己的称为统一算法的算法,而不是使用random % alphabet
-
兼容性好,NanoID 支持 14 种不同的编程语言,分别是C#, C++, Clojure and ClojureScript, Crystal, Dart & Flutter, Deno, Go, Elixir, Haskell, Janet, Java, Nim, Perl, PHP, Python with dictionaries, Ruby , Rust, Swift
-
NanoID的另一个现有特点是它允许开发者使用自定义字母。你可以改变字面意思或ID的大小
-
无第三方依赖,由于NanoID不依赖于任何第三方的依赖,随着时间的推移,它变得更加稳定的自我管理。从长远来看,这有利于优化包的大小,并使其不容易出现依赖性带来的问题
了解 NanoID 及其用途
当涉及到JavaScript时,生成UUID或NanoID是非常简单。它们都有NPM包来帮助你。
你所需要做的就是使用npm i nanoid命令安装NanoID NPM库,并在你的项目中使用它。
import { nanoid } from 'nanoid';model.id = nanoid();
下图显示了这两者之间的npm趋势对比,我们可以看到NanoID的上升趋势,而UUID的进展则很平缓。

希望这些数字已经说服您尝试 NanoID。
NanoID局限性
根据 StackOverflow 中的许多专家意见,使用 NanoID 没有明显的缺点或限制。
非人类可读是许多开发人员在 NanoID 中看到的主要缺点,因为它使调试变得更加困难。但是,与 UUID 相比,NanoID 更短且可读。
另外,如果使用 NanoID 作为表的主键,如果使用同一列作为聚集索引,也会出现问题。这是因为 NanoID 不是连续的
NanoID将来
NanoID 逐渐成为 JavaScript 最流行的唯一 id 生成器,大多数开发人员更愿意选择它而不是 UUID。
$ node ./test/benchmark.jscrypto.randomUUID 25,603,857 ops/sec@napi-rs/uuid 9,973,819 ops/secuid/secure 8,234,798 ops/sec@lukeed/uuid 7,464,706 ops/secnanoid 5,616,592 ops/seccustomAlphabet 3,115,207 ops/secuuid v4 1,535,753 ops/secsecure-random-string 388,226 ops/secuid-safe.sync 363,489 ops/seccuid 187,343 ops/secshortid 45,758 ops/sec Async:nanoid/async 96,094 ops/secasync customAlphabet 97,184 ops/secasync secure-random-string 92,794 ops/secuid-safe 90,684 ops/sec Non-secure:uid 67,376,692 ops/secnanoid/non-secure 2,849,639 ops/secrndm 2,674,806 ops/sec
上述基准测试显示了 NanoID 与其他主要 id 生成器相比的性能。
它使用默认字母表每秒可生成超过 220 万个唯一 ID,使用自定义字母表时每秒可生成超过 180 万个唯一 ID。
考虑到它的小尺寸、URL 友好性、安全性和速度,我建议在未来的任何项目中使用 NanoID 而不是 UUID。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/933807.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!