博客横幅

什么是 UUID?它有什么用途?

发布日期 2023 年 6 月 29 日

0 分钟阅读

    读者须知:本文引用了 CockroachDB Serverless 和/或 CockroachDB Dedicated,自 2024 年 9 月 26 日起,它们已更名并纳入新的 CockroachDB Cloud 平台,您可以 阅读更多内容

    使用数据库时,通常使用某种 id 字段为表中的每一行提供唯一的标识符。

    例如,想象一下 customers 表。我们不想使用诸如 name 或者 address 作为唯一标识符,因为可能多个客户具有相同的名称,或共享相同的地址,或者在某些情况下甚至两者兼而有之!

    相反,最好给每一行分配某种 确实 唯一标识符。我们的一个选项是使用 UUID。

    什么是 UUID? 复制图标

    UUID 代表什么?UUID(通用唯一标识符)是一个 36 个字符的字母数字字符串,可用于识别信息。例如,它们通常用于识别数据库表中的数据行,每行分配一个特定的 UUID。

    以下是 UUID 的一个示例: acde070d-8c4c-4f0d-9d8a-162843c10333

    UUID 之所以被广泛使用,部分原因是它们很可能是唯一的 全球 ,这意味着我们行的 UUID 不仅在我们的数据库表中是唯一的,而且它可能是任何系统中唯一具有该 UUID 的行 任何地方

    (从技术上讲,它不是 不可能的 我们生成的相同 UUID 可以在其他地方使用,但由于存在 340,282,366,920,938,463,463,374,607,431,768,211,456 个不同的 UUID,因此可能性很大 非常 苗条的)。

    UUID 用于什么? 复制图标

    为了回答这个问题,我们假设我们经营一家电子商务书店。当订单进来时,我们希望为它们分配一个 ID 号,并将其存储在我们的 orders 使用该数字的表格。

    我们 可以 设置顺序 ID,以便第一个到达的订单是 1 ,第二个是 2 等等,例如:

    如果我们的规模较小,这种方法可能至少在一段时间内会很有效。然而,它有一些重大缺点:

    第一的 ,当我们进行诸如连接表或导入新数据之类的操作时,它很容易造成混乱,因为 id 上面的值不是唯一的。如果我们对多个表使用相同的 ID 系统,这甚至会在内部产生问题,而且当我们开始处理任何类型的外部数据时,情况就会变得非常混乱。

    例如,想象一下,我们的小书店发展壮大,我们收购了另一家网上书店。当我们整合我们的 order 表格中,我们发现他们使用了相同的系统。现在我们有两个订单 1 s,二阶 2 等,为了解决这个问题,我们必须更新 每一个身份证 至少在我们集成的两个数据库中有一个。即使在最好的情况下,这也将是一个巨大的麻烦。

    第二 在分布式系统中,顺序方法通常效果不佳,因为使用顺序 ID 意味着 INSERT 命令必须逐个执行。此限制可能会导致严重的性能问题,因为您的数据库节点必须等待一个节点一次写入数据,而不是让所有节点能够同时写入。即使您的应用程序需要严格的 ID 排序,使用 CockroachDB 的 变更数据捕获 可能允许您满足这些要求,同时仍然使用 UUID,并且不会承受按顺序排序的 ID 带来的性能损失。

    其他传统的获取唯一 ID 的方法,例如使用 SERIAL ,也可能导致分布式系统中的热点,因为大约在同一时间生成的值通常相似,因此可能在表的存储中彼此靠近。例如,在 CockroachDB 中, 这可能会导致一个节点过度劳累的热点 因为它处理大多数或所有的写入操作,而其他节点则处于空闲状态。

    UUID 解决了所有这些问题,因为:

    • 它们是全局唯一的,因此即使在外部数据中遇到重复 ID 的可能性也非常大, 非常 小的。

    • 它们可以在不需要检查中心节点的情况下生成,因此在分布式系统中,每个节点都可以自主生成 UUID,而不必担心重复或一致性问题。

    仅凭原因 1 就足以说明在几乎所有数据库系统中使用 UUID 的合理性。作为一家渴望大规模运营的企业,原因 2 也与我们的书店息息相关,因为分布式数据库具有最佳的可扩展性和弹性。

    UUID 的缺点 复制图标

    UUID 的唯一显著缺点是它们占用 128 位内存(如果包含元数据,占用的内存通常会更多)。如果最小化存储空间绝对是任务关键,那么存储连续 ID(可能介于 1-10 个数字字符之间)显然会更加

    然而,在大多数情况下,使用诸如顺序标识符之类的缺点远远超过使用 UUID 所带来的存储成本的微小增加。

    UUID 有什么用?UUID 非常流行,广泛用于各种不同的识别目的。我们在本文中重点介绍数据库示例,因为 我们创建了一个非常棒的数据库 但 UUID 也用于分析系统、Web 和移动应用程序等。

    在大多数数据库中,查找 UUID 的方法都很简单。例如,在 CockroachDB 中,您可以通过查询相关表来检索特定行的 UUID。

    UUID 示例 复制图标

    UUID 有几种不同的类型:

    版本 1 和版本 2。 这些 ID 有时也称为基于时间的 UUID,它们是使用日期时间值(反映生成 UUID 的时间)、随机值和生成 UUID 的设备的 MAC 地址的一部分的组合生成的。

    其直观分解如下:

    什么是 uuid 静态

    以这种方式生成 UUID 几乎不可能拥有相同的 UUID - 它们必须由同一设备在完全相同的时间生成 生成了完全相同的随机16位序列。

    由于它们包含生成设备的 MAC 地址的一部分,因此 UUID v1 和 UUID v2 ID 可用于识别(例如)哪个数据库节点生成了该 ID。这通常不是问题,并且在分布式系统中,这可能是一个优势。

    (v1 和 v2 UUID 之间的区别在于 UUID v2 还包含一段本地域号。由于多种原因,这使得它们对于大多数应用程序来说不是最优的,因此 UUID v2 并未得到广泛使用。)

    版本 3 和版本 5 。这两个版本的 UUID 是通过对命名空间标识符和名称进行哈希处理生成的。它们与基于时间的 UUID 类似,因为它们是使用现有数据生成的,而不是完全随机的,但它们不是使用日期时间数据和设备 MAC 地址,而是使用命名空间数据和名称数据。

    命名空间数据本身就是一个 UUID,而名称数据实际上可以是任意字符串,尽管在实践中它通常与 UUID 的使用方式有关 - 例如,它可能是帐户名称或产品 ID。但无论使用这两个值是什么,它们都会被哈希处理以生成一个 36 个字符的字母数字字符串,即最终的 UUID。

    UUID 版本 3 和 5 的主要区别在于它们使用不同的哈希算法。UUID v3 使用 MD5 以及 UUID v5 用途 SHA-1

    版本 4 。这些 UUID 大多是随机生成的 36 个字符的字符串。从技术上讲,每个字符串中的几个字符是从日期时间值生成的,但大多数都是随机或伪随机的。请参阅 请参阅本文以了解具体细节。

    由于生成过程完全随机,因此它们极有可能是唯一的。它们也不包含日期时间、MAC 地址或名称数据等识别信息(这可能是优点也可能是缺点,具体取决于具体用例)。

    版本 6、7 和 8 截至撰写本文时,这些版本均不存在,但它们已被提出,并可能在未来几年内添加到 UUID 标准中。您可以阅读有关这些提议的新 UUID 的更多信息 这里

    如何生成 UUID 复制图标

    UUID 可能看起来很复杂,但在现代应用程序开发环境中,生成 UUID 实际上非常简单。大多数流行的编程语言都有库,使生成 UUID 变得像调用函数一样简单。这些库通常包含一个 UUID 生成器函数,可简化该过程,利用随机生成器来确保唯一性。”

    例如,在 JavaScript 中,你只需导入 uuid 包裹 然后调用 uuid.v1() 例如,生成 UUID v1。Python 非常类似:导入 uuid 并调用 uuid.uuid1() 生成 UUID v1。

    数据库,特别是分布式数据库,也可能具有内置的 UUID 生成功能。例如,在 CockroachDB 中, 我们建议使用 UUID 作为行标识符,这样做很简单,只需使用 gen_random_uuid() 功能。

    因此,例如,当我们使用 SQL 创建表时,我们可以确保它为每一行自动生成一个 UUID v4,如下所示:

    CREATE TABLE users ( id UUID NOT NULL DEFAULT gen_random_uuid(), city STRING NOT NULL, name STRING NULL, address STRING NULL, credit_card STRING NULL, CONSTRAINT "primary" PRIMARY KEY (city ASC, id ASC), FAMILY "primary" (id, city, name, address, credit_card) );

    每次将一行插入到此表中时, id 值将是自动生成的 UUID。

    长话短说:生成和使用 UUID 通常非常简单。具体实现细节可能因我们使用的特定数据库技术和/或编程语言而略有不同,但在大多数情况下,归根结底就是调用某种 generate_uuid() 函数。

    尝试 CockroachDB Cloud

    数分钟内即可启动您的第一个集群。以 400 美元的免费积分开始。

    分布式数据库中的 UUID 复制图标

    分布式 SQL 数据库 提供强大的组合:NoSQL 数据库的弹性规模和恢复能力与 SQL 数据库的事务一致性和熟悉度相结合。

    然而,使用分布式系统确实意味着需要以不同的方式处理某些事情。正如我们前面提到的,生成行 ID 的传统方法,例如通过将 1 添加到整数来生成顺序 ID,以便将行标识为 2 , 3 , 4 等方法在分布式系统中效果不佳。这些方法会导致“热点”节点并造成性能瓶颈。

    UUID 为许多分布式工作负载提供了一种更好的替代方案,因为数据库中的每个节点都可以自主生成完全唯一的 UUID,而无需与其他节点进行检查。

    但这并不意味着 UUID 总是最好的选择。在 CockroachDB 中,使用 UUID 通常效果很好,但使用 多列主键 在某些情况下可以提供卓越的性能(尽管设置和测试也更复杂)。

    亲自动手 复制图标

    想要亲自尝试在分布式数据库中使用 UUID 吗?CockroachDB Serverless 是免费的,您可以在不到五分钟的时间内启动新集群并创建表并插入数据。 一探究竟!

    sql
    分布式 SQL
    分布式数据库