UUID
类型的列,我如何指定要自动生成的UUID作为任何行插入的默认值?#1 楼
tl; dr在定义列以调用OSSP uuid函数之一时调用
DEFAULT
。每次插入行时,Postgres服务器都会自动调用该函数。 CREATE TABLE tbl
(
pkey UUID NOT NULL DEFAULT uuid_generate_v1() ,
CONSTRAINT pkey_tbl PRIMARY KEY ( pkey )
)
如果您已经使用pgcrypto扩展名,请考虑使用bpieck回答。
生成UUID所需的插件
Postgres开箱即用支持以其本机128位格式存储UUID(通用唯一标识符)值,从而生成UUID值需要一个插件。在Postgres中,一个插件称为
extension
。 要安装扩展程序,请致电
CREATE EXTENSION
。为避免重新安装,请添加IF NOT EXISTS
。有关更多详细信息,请参见我的博客文章。或在StackOverflow中查看此页面。我们想要的扩展是一个用C内置的开放源代码库,用于处理UUID和OSSP uuid。这个用于Postgres的库的构建通常与Postgres的安装捆绑在一起,例如Enterprise DB提供的图形安装程序,或者包括诸如Amazon RDS for 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,外加“无” 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值的标志。 要比较类型,请参阅问题,使用哪个UUID版本?
如果您仅对版本4(随机生成)感兴趣,并且已经使用pgcrypto,请参阅bpieck的答案。
如果您对版本3和5感到好奇,请参阅此问题,生成v5 UUID。名称和名称空间是什么?。
有关更多讨论,请参见我对类似问题的解答以及我的博客文章JDBC到Postgres的UUID值。
#2 楼
pgcrypto扩展
对Basil的非常详细的答案仅作了一点补充。
由于当前大多数人都在使用pgcrypto,因此您可以将
uuid_generate_v4()
用作版本4,而不是gen_random_uuid()
UUID值。 首先,在Postgres中启用pgcrypto。
CREATE EXTENSION "pgcrypto";
只需将列的默认值设置为
DEFAULT gen_random_uuid()
评论
如何创建UUID类型的列,在Google中有1,000,000次点击。零命中率如何使该pk成为查询行! :-@
–克林特·伊斯特伍德
18年7月9日在17:31
@ClintEastwood对类似问题的“我的答案”,以及我的博客文章,从JDBC到Postgres的UUID值都可以为您提供帮助。如果证明不足,请发布新问题。我很乐意再试一次。我了解您的无奈!
–罗勒·布尔克
18年7月9日在19:30
@ClintEastwood:将UUID列与值进行比较的语法遵循手册中记录的常量的语法:postgresql.org/docs/current/static/…,并键入强制类型转换:postgresql.org/docs/current/static/…
– a_horse_with_no_name
18年7月9日在19:51
@BasilBourque:不必强制转换getObject()的结果,也可以使用UUID id = rs.getObject(“ uuid_”,UUID.class);
– a_horse_with_no_name
18年7月9日在19:53
@Rokit要验证随机数生成器的强度,请查看由此Postgres扩展包装的底层开源实现,这是我的答案中提到的OSSP uuid库项目。请记住,如果出于某些原因您不能选择其他类型,则只能将第四版UUID用作最后的手段。通常,通过调用uuid_generate_v1或uuid_generate_v1mc,您的首选应该是Version 1。
–罗勒·布尔克
19年1月19日在1:11