暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

什么是 UUID,为什么我们要关心?

原创 谭磊Terry 恩墨学院 2022-07-16
1433

了解有关 UUID 的更多信息并了解它们存在的原因、缺点、不同类型等等!

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

例如,想象一下一张customers桌子。例如,我们不希望使用name或address作为唯一标识符之类的字段,因为可能有多个客户可能具有相同的名称或共享相同的地址。

相反,为每一行分配某种唯一标识符是个好主意。我们有一个选择是使用 UUID。

什么是 UUID?

顺便说一下,UUID 是 Universally Unique IDentifier 的缩写,是一个 36 个字符的字母数字字符串,可用于标识信息(例如表格行)。

这是 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,依此类推,如下所示:
image.png

如果我们的规模很小,这种方法可能会运作良好,至少在一段时间内。但是,它有一些主要缺点:

首先,当我们在做诸如连接表或导入新数据之类的事情时,它很容易造成混乱,因为id上面的值不是唯一的。即使我们对多个表使用相同的 ID 系统,这也会在内部产生问题,但是当我们开始处理任何类型的外部数据时,它确实会变得混乱。

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

其次,顺序方法在任何类型的分布式系统中都不能很好地工作,因为它意味着 INSERT 命令必须一个一个地执行。此限制可能会导致大规模的主要性能问题。即使您的应用程序需要严格的 ID 排序,使用某个特性也可以让您在满足这些要求的同时仍然使用 UUID,并且不会受到按顺序排序的 ID 带来的性能损失。

其他传统的唯一 ID 方法,例如使用生成随机 ID SERIAL,也可能导致分布式系统中的热点,因为大约在同一时间生成的值具有相似的值,因此在表的存储中彼此靠近。

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

它们是全球唯一的,因此即使在外部数据中遇到重复 ID 的机会也非常非常小。它们可以在不需要检查中心节点的情况下生成,因此在分布式系统中,每个节点都可以自主生成 UUID,而不必担心重复或一致性问题。

单独的原因 #1 是在几乎任何数据库系统中使用 UUID 的一个很好的论据。作为一家渴望大规模运营的企业,原因 2 也与我们的书店非常相关,因为分布式数据库提供了最佳的可扩展性和弹性。

UUID 的缺点

UUID 的唯一显着缺点是它们在内存中占用 128 位(当我们包含元数据时通常会更多)。如果最小化存储空间绝对是关键任务,那么显然存储顺序 ID(可能介于 1-10 个数字字符之间)将比存储 36 个字符的字母数字更有效。

然而,在大多数情况下,使用诸如顺序标识符之类的东西的缺点明显超过了使用 UUID 所带来的最小存储成本增加。UUID 非常流行并广泛用于各种不同的识别目的。我们在本文中专注于数据库示例,因为 UUID 也用于分析系统、Web 和移动应用程序等。

UUID 的类型

有几种不同类型的 UUID:

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

以下是它在视觉上的分解方式:
image.png

以这种方式生成 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 个字符的字符串。除了一个4表示它们是 v4 UUID 之外,每个字符只是一个从 az 或从 0-9 的整数的随机字符。

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

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

如何生成 UUID

UUID 可能看起来很复杂,但在现代应用程序开发的上下文中,生成它们实际上非常简单。大多数流行的编程语言都有库,可以让生成 UUID 就像调用函数一样简单。

例如,在 JavaScript 中,您只需导入包uuid,然后调用uuid.v1(),例如,生成 UUID v1。Python 非常相似:您导入并调用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()”函数。

分布式数据库中的 UUID

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

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

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

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

原文标题:What Is a UUID and Why Should You Care?
原文作者:Charlie Custer
原文地址:https://dzone.com/articles/what-is-a-uuid-and-why-should-you-care

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论