Postgres 中 UUID 列的默认值

Bas*_*que 96 postgresql default-value uuid

Postgres 9.x 中,对于类型为 的列UUID,如何指定要自动生成的 UUID 作为任何行插入的默认值?

Bas*_*que 135

tl;博士

呼叫DEFAULT定义列调用之一,当OSSP的uuid功能。每次插入一行时,Postgres 服务器都会自动调用该函数。

CREATE TABLE tbl 
(
  pkey UUID NOT NULL DEFAULT uuid_generate_v1() , 
  CONSTRAINT pkey_tbl PRIMARY KEY ( pkey )
)
Run Code Online (Sandbox Code Playgroud)

如果您已经使用pgcrypto扩展,请考虑bpieck答案

生成 UUID 所需的插件

虽然Postgres开箱即用支持以原生128 位形式存储 UUID(通用唯一标识符)值,但生成UUID 值需要插件。在 Postgres 中,插件被称为.extension

要安装扩展程序,请调用CREATE EXTENSION。为避免重新安装,请添加IF NOT EXISTS. 有关更多详细信息,请参阅我的博客文章,或在 StackOverflow 中查看此页面

我们想要的扩展是一个用 C 语言构建的开源库,用于处理 UUID,OSSP uuid。甲此库的Postgres生成通常与的Postgres的安装捆绑诸如提供的图形安装企业DB或包括在由云提供商如亚马逊RDS对PostgreSQL

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
Run Code Online (Sandbox Code Playgroud)

生成各种UUID

请参阅扩展的文档以查看用于生成各种 UUID 值的多个命令的列表。要从计算机的MAC 地址加上当前日期时间加上一个小的随机值来获取原始版本的 UUID ,请调用uuid_generate_v1().

SELECT uuid_generate_v1();
Run Code Online (Sandbox Code Playgroud)

672124b6-9894-11e5-be38-001d42e813fe

此主题的后续变体是为替代类型的 UUID 开发的。有些人可能不想记录服务器的实际 MAC 地址,例如出于安全或隐私考虑。Postgres 扩展生成五种 UUID,加上“nil”UUID 00000000-0000-0000-0000-000000000000

UUID 作为默认值

该方法调用可以自动为任何新插入的行生成默认值。定义列时,指定:

DEFAULT uuid_generate_v1()

请参阅以下示例表定义中使用的命令。

CREATE TABLE tbl 
(
  pkey UUID NOT NULL DEFAULT uuid_generate_v1() , 
  CONSTRAINT pkey_tbl PRIMARY KEY ( pkey )
)
Run Code Online (Sandbox Code Playgroud)

UUID 版本

UUID-OSSP插件可以生成UUID的各种版本

  • uuid_generate_v1()
    包含当前计算机的MAC地址+当前时刻。常用,但如果您对披露数据库服务器的 MAC 或生成此值的时间很敏感,请避免使用。由规范定义为版本 1 UUID
  • uuid_generate_v1mc()
    版本 1类似,但使用随机多播 MAC 地址而不是真实 MAC 地址。显然是一种使用版本 1 的方法,但如果您对披露该事实很敏感,则替换另一个 MAC 而不是数据库服务器的实际 MAC。
    什么是“随机多播 MAC”?我不知道。阅读RFC 4122 的第 4.1.6 节后,我怀疑这是一个随机数,用于代替 MAC,但设置的位指示多播 MAC 地址而不是通常的单播,以便将版本 1 的这种变体与通常的区别real-MAC 版本 1 UUID。
  • uuid_generate_v3( namespace uuid, name text )
    包含您提供的文本的MD5 哈希值。由规范定义为版本 3 UUID,基于命名空间的 UUID。
  • uuid_generate_v4()
    基于 128 位中的 121-122 位随机生成的数据。六七用于指示版本和变异。这种 UUID 仅在使用加密强随机生成器实现时才实用。由规范定义为版本 4 UUID
  • uuid_generate_v5( namespace uuid, name text )
    与版本 3 相同,但使用SHA1散列。由规范定义为Version 5 UUID
  • uuid_nil()
    一种特殊情况,所有位都设置为零00000000-0000-0000-0000-000000000000。用作未知 UUID 值的标志。称为nil UUID

要比较类型,请参阅问题,要使用哪个 UUID 版本?

如果您只对版本 4(随机生成)感兴趣,并且已经在使用pgcrypto,请参阅bpieck答案

如果您对版本 3 和 5 感到好奇,请参阅此问题,生成 v5 UUID。什么是名称和命名空间?.

有关更多讨论,请参阅对类似问题的回答和我的博客文章UUID 值从 JDBC 到 Postgres


小智 18

pgcrypto扩展

只是罗勒非常详细的答案的一小部分。

由于目前大多数都在使用pgcrypto,因此uuid_generate_v4()您可以将其gen_random_uuid()用于版本 4 UUID值。

首先,在你的 Postgres 中启用pgcrypto

CREATE EXTENSION "pgcrypto";
Run Code Online (Sandbox Code Playgroud)

只需将列的 DEFAULT 设置为

DEFAULT gen_random_uuid()
Run Code Online (Sandbox Code Playgroud)

  • 使用这两种方法生成了 1 亿个 uuid,它们的生成时间几乎相同 ~ 9 秒。(在 Postgres 14 下测试 - 该功能不再需要 pgcrypto 扩展) (5认同)
  • 出于好奇,两者之间有性能差异吗? (2认同)

Luk*_*sis 11

如果使用 Postgres 13 或更高版本,您不需要任何修改或额外的插件,只需使用gen_random_uuid()

刚刚在默认的 AWS Aurora Serverless v2 和 Postgres v14 上进行了测试

ps你可以看到我的默认id实际上是带有前缀的,wor-而它是工作区id。我向所有表添加前缀,这样当我从任何地方(日志、支持等)获取 ID 时,我就可以准确地知道要搜索的内容。

concat('wor-', gen_random_uuid())

在此输入图像描述

在此输入图像描述