Postgres 的性能比其他一些数据库更好,因为它支持并发写入操作,而不需要读/写锁。因为它完全符合 ACID 并提供事务隔离和快照,所以现在许多应用程序都在使用 Postgres。不幸的是,虽然 PostgreSQL 非常适合存储和比较 UUID 数据,但它的核心缺乏创建 UUID 值的功能。相反,它依赖第三方模块使用指定的技术创建 UUID。在本文中,您将了解 PostgreSQL UUID 数据类型以及如何通过利用各种函数和模块的示例生成 UUID 值。
什么是 UUID?
UUID 代表通用唯一标识符,由RFC 4122和其他相关标准定义。UUID 是一系列由连字符分隔的小写十六进制数字。UUID 是 36 个字符的数字、字母和破折号序列的组合,旨在实现全局唯一。
由于这种奇妙的特性,UUID 经常在分布式系统中使用,因为它比SERIAL数据类型确保更多的唯一性,SERIAL 数据类型仅在单个数据库中创建唯一的条目。不同的计算机可以在不进行通信的情况下同时产生UUID,并且UUID将被保证是唯一的。使用 UUID 的独立系统可以随时安全地组合在一起,而不必担心发生冲突。Postgres 中的 uuid 列数据类型支持全局唯一标识符 (UUID)。如果您的表有 UUID 列,您可能需要生成 UUID。由于没有一种技术能够完美适合所有应用程序,因此 PostgreSQL 具有 UUID 的存储和比较功能,但没有在核心数据库中生成 UUID 的功能。
为什么 Postgres 不自己生成 UUID?
PostgreSQL 允许您存储和比较 UUID 值,但它没有任何用于创建它们的内置方法。这就是开发这篇文章的原因 - 向您展示在 Postgres 中生成 UUIDS 的几种方法。
如何在 Postgres 中生成 UUIDS
方法一:使用uuid-ossp模块
如上所述,PostgreSQL 允许您存储和比较 UUID 值,但它没有任何内置方法来创建它们。相反,它依赖于使用指定技术创建 UUID 的第三方模块。例如,uuid-ossp 模块具有各种有用的方法来实现常见的 UUID 生成技术。要安装 uuid-ossp 模块,请使用 CREATE EXTENSION 语句,如下所示:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
该IF NOT EXISTS
子句允许您避免重新安装模块。要根据计算机的 MAC 地址、当前时间戳和随机值的组合生成 UUID 值,请使用 uuid_generate_v1() 函数:SELECT uuid_generate_v1();
在此示例中,该函数生成以下 UUID 值:
uuid_generate_v1
--------------------------------------
0e37df36-f698-11e6-8dd4-cb9ced3df976
(1 row)
如果您想仅根据随机数生成 UUID 值,可以使用 uuid_generate_v4() 函数。例如:
SELECT uuid_generate_v4();
uuid_generate_v4
--------------------------------------
a81bc81b-dead-4e5d-abff-90865d1e13b1
(1 row)
方法 2:使用 gen_random_uuid() 模块
PostgreSQL 发行版中包含了其他提供的模块,但默认情况下并未安装它们。任何具有 CREATE 权限的用户帐户都可以安装模块。在pgcrypto模块中,有一个名为 gen_random_uuid() 的 uuid 生成方法,它使用版本 4 算法创建完全由随机十六进制整数组成的 uuid。
以下 SQL 命令用于查找所有可用的扩展。他们还将显示当前已安装的列表。
SELECT * FROM pg_avilable_extensions ORDER BY name;
-- list available extensions
SELECT * FROM pg_extension;
-- list installed extensions
要安装 pgcrypto 扩展,请使用以下命令。
CREATE EXTENSION IF NOT EXISTS "pgcrypto"; -- creates extension
安装 pgcrypto 扩展后,以下命令将返回一个随机 UUID:
SELECT gen_random_uuid(); -- generate a random uuid of version 4
842d3fae-7788-4ecb-b441-7c7e8130b8bf
gen_random_uuid() 和 uuid_generate_v4() 之间的区别
gen_random_uuid() 和 uuid_generate_v4() 都会生成 UUID。
建议使用 gen_random_uuid()。如果您只需要随机生成(版本 4)UUID。此外,uuid-ossp 扩展还提供其他类型的 UUID(例如基于 mac 地址的)。
另一个需要考虑的因素是这些工具用来生成随机值的不同方法:uuid_generate_v4() 使用 arc4random 来确定随机部分,而 gen_random_uuid() 使用 Fortuna 代替。
我应该使用 UUID 作为我的主键吗?
这取决于很多事情。
- 由于 UUID 是唯一的,因此您可以将其用作数据库中的主键。但请记住,UUID 比 SEQUENCE 占用的空间多一些。它们的生成速度也很慢。然而,它们无疑是独一无二的,可确保您收到准确的数据。
- UUID 编号在表、数据库甚至服务器中都是唯一的,允许您组合多个数据库中的条目或将数据库分布在多个服务器上。由于 UUID 值不会泄露有关您的数据的信息,因此在 URL 中使用它们更安全。这一好处可以让使用 UUID 的成本变得值得。