关于postgresql:在Postgres中为插入语句生成UUID吗?

Generating a UUID in Postgres for Insert statement?

我的问题很简单。 我知道UUID的概念,我想生成一个引用UDB的"存储"中的每个"项目"。 看起来合理吧?

问题是以下行返回错误:

1
2
3
4
5
6
honeydb=# INSERT INTO items VALUES(
uuid_generate_v4(), 54.321, 31, 'desc 1', 31.94);
ERROR:  FUNCTION uuid_generate_v4() does NOT exist
LINE 2: uuid_generate_v4(), 54.321, 31, 'desc 1', 31.94);
        ^
HINT:  No FUNCTION matches the given name AND argument types. You might need TO ADD explicit TYPE casts.

我已在以下位置阅读该页面:http://www.postgresql.org/docs/current/static/uuid-ossp.html

enter image description here

我在Ubuntu 10.04 x64上运行Postgres 8.4。


uuid-ossp是一个contrib模块,因此默认情况下不会加载到服务器中。您必须将其加载到数据库中才能使用。

对于现代PostgreSQL版本(9.1及更高版本),这很容易:

1
CREATE EXTENSION IF NOT EXISTS"uuid-ossp";

但对于9.0及以下版本,您必须改为运行SQL脚本来加载扩展。请参阅8.4中的contrib模块文档。

对于Pg 9.1及更高版本,请阅读当前的contrib文档和CREATE EXTENSION。这些功能在9.0或更早的版本(例如8.4)中不存在。

如果您使用的是PostgreSQL的打包版本,则可能需要安装包含contrib模块和扩展名的单独软件包。在软件包管理器数据库中搜索" postgres"和" contrib"。


没有扩展名(作弊)

1
2
3
SELECT uuid_in(md5(random()::text || clock_timestamp()::text)::cstring);

output>> c2d29867-3d0b-d497-9191-18a9d8ee7830

(至少在8.4中有效)

  • 感谢@Erwin Brandstetter提供的clock_timestamp()解释。

如果您需要有效的v4 UUID

1
SELECT uuid_in(overlay(overlay(md5(random()::text || ':' || clock_timestamp()::text) placing '4' FROM 13) placing to_hex(FLOOR(random()*(11-8+1) + 8)::INT)::text FROM 17)::cstring);

enter image description here
*感谢@Denis Stafichuk @Karsten和@autronix

另外,在现代Postgres中,您可以简单地进行以下转换:

SELECT md5(random()::text || clock_timestamp()::text)::uuid


Craig Ringer的答案是正确的。这是Postgres 9.1及更高版本的更多信息……

可以使用分机吗?

如果已为Postgres安装(您的集群使用Postgres术语)构建了扩展名,则只能安装该扩展名。例如,我发现uuid-ossp扩展包含在EnterpriseDB.com提供的Mac OS X安装程序的一部分中。几十个扩展中的任何一个都可用。

要查看uuid-ossp扩展在Postgres集群中是否可用,请运行以下SQL查询pg_available_extensions系统目录:

1
SELECT * FROM pg_available_extensions;

安装扩展

要安装与UUID相关的扩展,请使用此SQL中所示的CREATE EXTENSION命令:

1
CREATE EXTENSION IF NOT EXISTS"uuid-ossp";

请注意:尽管有相反的说明,但我发现仍需要在扩展名周围使用QUOTATION MARK字符。

SQL标准委员会或Postgres团队为此命令选择了一个奇怪的名称。在我看来,他们应该选择"安装扩展"或"使用扩展"之类的东西。

验证安装

您可以通过运行以下SQL查询pg_extension系统目录来验证扩展已成功安装在所需的数据库中:

1
SELECT * FROM pg_extension;

UUID作为默认值

有关更多信息,请参见Postgres中的"问题:UUID的默认值"列

旧方法

上面的信息使用了Postgres 9.1中新增的扩展功能。在以前的版本中,我们必须在.sql文件中查找并运行脚本。添加了扩展功能,以简化安装,为扩展的创建者交易了更多的工作,而减少了扩展的用户/用户的工作。请参阅我的博客文章以获取更多讨论。

UUID的类型

顺便说一句,Question中的代码调用了函数uuid_generate_v4()。这将生成一种称为版本4的类型,其中几乎所有128位都是随机生成的。尽管这对于限制在较小的行集上的有限使用是很好的,但是如果您想消除冲突的可能性,请使用UUID的另一个"版本"。

例如,原始版本1将主机的MAC地址与当前日期时间和任意数字结合在一起,发生冲突的机会几乎为零。

有关更多讨论,请参见我对相关问题的回答。


pgcrypto扩展名

从Postgres 9.4开始,pgcrypto模块包含gen_random_uuid()函数。此函数生成基于随机数的UUID版本4类型之一。

获取contrib模块(如果尚不可用)。

1
sudo apt-GET install postgresql-contrib-9.4

使用pgcrypto模块。

1
CREATE EXTENSION"pgcrypto";

gen_random_uuid()函数现在应该可用;

用法示例。

1
INSERT INTO items VALUES( gen_random_uuid(), 54.321, 31, 'desc 1', 31.94 ) ;

引用uuid-ossp模块上的Postgres文档。

Note: If you only need randomly-generated (version 4) UUIDs, consider using the gen_random_uuid() function from the pgcrypto module instead.


1
ALTER TABLE TABLE_NAME ALTER COLUMN id SET DEFAULT uuid_in((md5((random())::text))::cstring);

阅读@ZuzEL的答案后,我将上面的代码用作列ID的默认值,并且工作正常。