在Postgres中为插入语句生成UUID ?

我的问题很简单。我知道一个UUID的概念,我想生成一个引用每个“项目”从一个“商店”在我的DB与。似乎很合理,对吧?

问题是下面这行返回了一个错误:

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。

685486 次浏览

uuid-ossp是一个贡献模块,所以默认情况下它不会加载到服务器中。必须将其加载到数据库中才能使用。

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

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

但是对于9.0及以下版本,您必须运行SQL脚本来加载扩展。看到# EYZ0。

对于9.1级及以上版本,请阅读当前的contrib文档CREATE EXTENSION。这些特性在9.0或更早的版本(如8.4)中不存在。

如果你正在使用PostgreSQL的打包版本,你可能需要安装一个包含contrib模块和扩展的单独包。在包管理器数据库中搜索'postgres'和'contrib'。

Craig Ringer的回答是正确的。下面是关于Postgres 9.1及以后版本的一些信息…

分机是否可用?

你只能安装一个已经为Postgres安装构建好的扩展(用Postgres行话来说就是集群)。例如,我发现uuid-ossp扩展作为Mac OS X安装程序的一部分包含在EnterpriseDB.com的提供中。几十个扩展中的任何一个都可以使用。

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

SELECT * FROM pg_available_extensions;

安装扩展

要安装与# eyz0相关的扩展,使用如下所示的创建扩展命令:

CREATE EXTENSION IF NOT EXISTS "uuid-ossp";

我发现扩展名周围的引号字符是必需的,尽管文档与此相反。

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

验证安装

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

SELECT * FROM pg_extension;

UUID为默认值

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

旧的方式

上面的信息使用了新的扩展特性添加到Postgres 9.1。在以前的版本中,我们必须在. sql文件中找到并运行脚本。扩展特性的添加使安装更容易,为扩展的创建者交易了更多的工作,以减少扩展的用户/消费者部分的工作。更多讨论请参阅我的博客

uuid的类型

顺便说一下,问题中的代码调用了函数uuid_generate_v4()。这将生成一个名为版本4的类型,其中几乎所有的128位都是随机生成的。虽然这对于在较小的行集上有限地使用是可以的,但如果您希望实际上消除任何冲突的可能性,请使用另一个“版本”的UUID。

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

更多讨论,见我的答案相关问题。

没有扩展(作弊)

如果您需要一个有效的v4 UUID

SELECT uuid_in(overlay(overlay(md5(random()::text || ':' || random()::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

或者你可以简单地通过这样做来获得类似uuid的值(如果你不关心有效性):

SELECT uuid_in(md5(random()::text || random()::text)::cstring);


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

(至少在8.4中有效)

# EYZ0扩展

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

获取贡献模块(如果尚未可用)。

sudo apt-get install postgresql-contrib-9.4

使用pgcrypto模块。

CREATE EXTENSION "pgcrypto";

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

使用例子。

INSERT INTO items VALUES( gen_random_uuid(), 54.321, 31, 'desc 1', 31.94 ) ;
< p > < br > 引用自Postgres doc在uuid-ossp模块

注意:如果您只需要随机生成的uuid(版本4),请考虑使用pgcrypto模块中的gen_random_uuid()函数。

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

在阅读@ZuzEL的回答后,我使用上面的代码作为列id的默认值,它工作得很好。

PostgreSQL 13支持本机 gen_random_uuid ():

PostgreSQL包含一个生成UUID的函数:

gen_random_uuid () → uuid

这个函数返回一个版本4(随机)UUID。这是最常用的UUID类型,适用于大多数应用程序。

db<>小提琴demo

从2021年更新, 在insert语句上自动生成uuid不需要花哨的技巧

只做一件事:

  1. DEFAULT gen_random_uuid ()的默认值设置为uuid列。

假设,你有一个这样的表:

CREATE TABLE table_name (
unique_id UUID DEFAULT gen_random_uuid (),
first_name VARCHAR NOT NULL,
last_name VARCHAR NOT NULL,
email VARCHAR NOT NULL,
phone VARCHAR,
PRIMARY KEY (unique_id)
);

现在你不需要做任何事情来自动插入uuid值到unique_id列。因为您已经为它定义了一个默认值。您只需将重点放在插入到其他列上,postgresql负责unique_id。下面是一个插入语句示例:

INSERT INTO table_name (first_name, last_name, email, phone)
VALUES (
'Beki',
'Otaev',
'beki@bekhruz.com',
'123-456-123'
)

注意,没有插入到unique_id中,因为它已经被处理了。

关于其他扩展,如uuid-ossp,如果你不满意postgres的标准gen_random_uuid ()函数,你可以带上它们。大多数时候,你不戴眼镜也没问题

uuid-ossp模块提供了生成uuid (universally unique identifier)的函数。

uuid_generate_v1()该函数生成版本1的UUID。

  1. 添加扩展

如果扩展名不存在,创建扩展名;

  1. 验证扩展

SELECT * FROM pg_extension;

  1. 运行查询
INSERT INTO table_name(id, columnn1, column2, column3,…)值 (uuid_generate_v1 () value1, value2, value3…);< / p >

验证表数据

SELECT uuid_generate_v5(uuid_ns_url (), 'test');