Postgres中UUID列的默认值


Answers:


92

tl; dr

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

CREATE TABLE tbl 
(
  pkey UUID NOT NULL DEFAULT uuid_generate_v1() , 
  CONSTRAINT pkey_tbl PRIMARY KEY ( pkey )
)

生成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";

生成各种UUID

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

SELECT uuid_generate_v1();

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

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

UUID作为默认值

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

DEFAULT uuid_generate_v1()

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

CREATE TABLE public.pet_
(
  species_ text NOT NULL,
  name_ text NOT NULL,
  date_of_birth_ text NOT NULL,
  uuid_ uuid NOT NULL DEFAULT uuid_generate_v1(),  -- <====
  CONSTRAINT pet_pkey_ PRIMARY KEY (uuid_)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE public.pet_
  OWNER TO postgres;

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哈希。由规范定义为版本5 UUID
  • uuid_nil()
    一种特殊情况,所有位都设置为零00000000-0000-0000-0000-000000000000。用作未知UUID值的标志。称为nil UUID

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

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

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


如何创建UUID类型的列,在Google中获得1,000,000次点击。零命中率如何使该pk成为查询行!:-@
克林特·伊斯特伍德

@ClintEastwood 对类似问题的“ 我的答案”,以及我的博客文章,从JDBC到Postgres的UUID值都可以为您提供帮助。如果这些证明不足,请发布新问题。我很乐意再尝试一下。我了解您的无奈!
罗勒·布尔克

@ClintEastwood:语法的UUID列具有值比较如下的手册中所涉及的常数的语法:postgresql.org/docs/current/static/...和类型转换:postgresql.org/docs/current/static/...
a_horse_with_no_name18年

1
@BasilBourque:不必强制转换结果,getObject()也可以使用UUID id = rs.getObject("uuid_", UUID.class);
a_horse_with_no_name

1
@Rokit要验证随机数生成器的强度,请查看由Postgres扩展包装的底层开放源代码实现,这是我的答案中提到的OSSP uuid库项目。请记住,如果由于某些原因您不能选择其他类型,则只能将第四版UUID用作最后的手段。通常,您的首选方法应该是第1版,方法是调用uuid_generate_v1uuid_generate_v1mc
罗勒·布尔克

7

pgcrypto扩展

只是罗勒(Basil)非常详细的答案的一小部分:

由于目前大多数正在使用pgcrypto,而不是uuid_generate_v1()你可以使用gen_random_uuid()一个版本4的UUID值。

首先,在您的Postgres中启用pgcrypto

CREATE EXTENSION "pgcrypto";

只需将列的DEFAULT设置为 DEFAULT gen_random_uuid()

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.