我的问题很简单。我知道 UUID 的概念,我想生成一个来引用我数据库中“商店”中的每个“项目”。看起来很合理吧?
问题是以下行返回错误:
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
https://i.stack.imgur.com/BDeZ3.png
我在 Ubuntu 10.04 x64 上运行 Postgres 8.4。
select dbo.uuid_generate_v4()
uuid-ossp
是一个贡献模块,因此默认情况下它不会加载到服务器中。您必须将其加载到数据库中才能使用它。
对于现代 PostgreSQL 版本(9.1 和更高版本),这很容易:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
但对于 9.0 及以下版本,您必须改为运行 SQL 脚本来加载扩展。请参阅the documentation for contrib modules in 8.4。
对于 Pg 9.1 和更新版本,请改为阅读 the current contrib docs 和 CREATE EXTENSION
。这些功能在 9.0 或更早版本中不存在,例如您的 8.4。
如果您使用的是 PostgreSQL 的打包版本,您可能需要安装一个包含 contrib 模块和扩展的单独包。在您的包管理器数据库中搜索“postgres”和“contrib”。
没有扩展名(作弊)
如果您需要有效的 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);
https://i.stack.imgur.com/OA6Qk.png
感谢@Denis Stafichuk @Karsten 和 @autronix
或者您可以通过这样做简单地获得类似 UUID 的值(如果您不关心有效性):
SELECT uuid_in(md5(random()::text || random()::text)::cstring);
output>> c2d29867-3d0b-d497-9191-18a9d8ee7830
(至少在 8.4 中有效)
uuid_in(md5(random()::text || now()::text)::cstring);
uuid-ossp
“更好”,但例如我正在处理一个 PostgreSQL 实例,我没有足够的权限来安装扩展。
clock_timestamp()
在这两种情况下都是更好的选择。与 now()
或 CURRENT_TIMESTAMP
不同,它是可变的并返回实际的当前时间。 SELECT uuid_in(md5(random()::text || clock_timestamp()::text)::cstring);
此外,在现代 Postgres 中,您可以简单地转换:SELECT md5(random()::text || clock_timestamp()::text)::uuid
- 不需要更多魔法。用例:stackoverflow.com/a/8335376/939860
select overlay(overlay(md5(random()::text || ':' || clock_timestamp()::text) placing '4' from 13) placing '8' from 17)::uuid;
PostgreSQL 13 原生支持 gen_random_uuid ():
PostgreSQL 包含一个生成 UUID 的函数: gen_random_uuid () → uuid 此函数返回版本 4(随机)UUID。这是最常用的 UUID 类型,适用于大多数应用程序。
create function gen_random_uuid() RETURNS uuid as $$ SELECT md5(random()::text || clock_timestamp()::text)::uuid $$ LANGUAGE SQL;
answer by Craig Ringer 是正确的。这是 Postgres 9.1 及更高版本的更多信息……
扩展可用吗?
如果扩展已经为您的 Postgres 安装构建(您的 cluster 在 Postgres 术语中),您只能安装扩展。例如,我发现 EnterpriseDB.com 将 uuid-ossp 扩展作为 Mac OS X 安装程序的一部分provided。 few dozen extensions 中的任何一个都可能可用。
要查看 uuid-ossp 扩展是否在您的 Postgres 集群中可用,请运行此 SQL 以查询 pg_available_extensions
系统目录:
SELECT * FROM pg_available_extensions;
安装扩展
要安装与 UUID 相关的扩展,请使用如下 SQL 中所示的 CREATE EXTENSION 命令:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
注意:我发现扩展名周围的引号字符是必需的,尽管文档相反。
SQL 标准委员会或 Postgres 团队为该命令选择了一个奇怪的名称。在我看来,他们应该选择“安装扩展”或“使用扩展”之类的东西。
验证安装
您可以通过运行此 SQL 查询 pg_extension
系统目录来验证扩展是否已成功安装在所需的数据库中:
SELECT * FROM pg_extension;
UUID 作为默认值
有关详细信息,请参阅问题:Default value for UUID column in Postgres
老路
以上信息使用 Postgres 9.1 的新 Extensions 功能 added。在以前的版本中,我们必须在 .sql 文件中查找并运行脚本。添加了扩展功能以简化安装,为 creator of an extension 换取更多的工作,以减少扩展的用户/消费者的工作。有关更多讨论,请参阅我的 blog post。
UUID 的类型
顺便说一句,问题中的代码调用了函数 uuid_generate_v4()
。这会生成一种称为 Version 4 的类型,其中几乎所有 128 位都是随机生成的。虽然这适用于较小的行集的有限使用,但如果您想几乎消除任何冲突的可能性,请使用 UUID 的另一个“版本”。
例如,原始的Version 1将主机的MAC address与当前日期时间和任意数字组合在一起,碰撞的可能性几乎为零。
如需更多讨论,请参阅相关问题的my Answer。
CREATE EXTENSION IF NOT EXISTS ...
pgcrypto 扩展
从 Postgres 9.4 开始,pgcrypto
模块包括 gen_random_uuid()
函数。此函数生成基于随机数的 Version 4 type of UUID 之一。
获取 contrib 模块(如果尚不可用)。
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 ) ;
引自 Postgres doc on uuid-ossp
模块。
注意:如果您只需要随机生成的(版本 4)UUID,请考虑使用 pgcrypto 模块中的 gen_random_uuid() 函数。
从 2021 年开始更新,无需花哨的技巧即可在 insert
语句上自动生成 uuid
。
只做一件事:
将 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 ()
功能不满意,可以启用它们。大多数时候,没有它们你应该没问题
gen_random_uuid()
在 core PostgreSQL 中可用(因此不需要安装任何扩展)。
negative side effect with respect to keyspace fragmentation
,那么:不,这不是问题:postgresql.org/message-id/… – 如对 brillout 答案的评论中所述
ALTER TABLE table_name ALTER COLUMN id SET DEFAULT uuid_in((md5((random())::text))::cstring);
阅读@ZuzEL 的答案后,我使用上面的代码作为列 id 的默认值,它工作正常。
uuid-ossp 模块提供生成通用唯一标识符 (UUID) 的功能
uuid_generate_v1() 此函数生成版本 1 UUID。
添加扩展
如果不存在“uuid-ossp”,则创建扩展;
验证扩展
选择 * 从 pg_extension;
运行查询
INSERT INTO table_name(id, column1, column2 , column3, ...) 值 (uuid_generate_v1(), value1, value2, value3...);
验证表数据
试试这个:
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
SELECT uuid_generate_v1();
激活后,您可以调用 uuid_generate_v1() 生成随机 UUID
SELECT uuid_generate_v5(uuid_ns_url (), 'test');
不定期副业成功案例分享
apt-get install postgresql-contrib
或类似的。尝试apt-cache search postgresql |grep contrib
找到您想要的包名称。postgresql-contrib
软件包,您将收到错误消息:ERROR: could not open extension control file "/usr/share/postgresql/9.3/extension/uuid-ossp.control" : 没有这样的文件或目录