UUID Gen

本文探讨了Twitter的雪花算法(snowflake)及其在不同环境中的应用实例,包括Erlang实现的去中心化有序唯一ID生成器Flake。此外还涉及了Java垃圾回收的可视化工具等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://github.com/twitter/snowflake/releases/tag/snowflake-2010

http://boundary.com/blog/2012/01/12/flake-a-decentralized-k-ordered-unique-id-generator-in-erlang/

 

http://heipark.iteye.com/category/126118

 

http://blog.sina.com.cn/s/blog_56fd58ab0100wga0.html

http://www.infoq.com/cn/articles/Visualizing-Java-Garbage-Collection

 

http://wenku.baidu.com/link?url=s0Ro6vR9JyqGbANbMXFr1CXPBMfsTBJFdhfew4dqiIpHli_Wl6FTBeb8e7ld8TEH8hPZdi7kAtLUz6zpM9aye164BeaPEA82OuTOCBjA5DS

<think>我们正在讨论如何在PostgreSQL中使用UUID作为主键。用户可能想要了解如何生成UUID,如何设置UUID主键,以及相关的操作。 根据引用内容,我们可以总结如下: 1. 生成UUID的方法: - 使用`uuid-ossp`扩展中的函数(如`uuid_generate_v1`, `uuid_generate_v4`等) - 从PostgreSQL 13开始,可以使用内置函数`gen_random_uuid()`来生成版本4(随机)的UUID,无需额外扩展。 2. 使用UUID作为主键的步骤: a. 安装`uuid-ossp`扩展(如果使用`uuid_generate_v4`且版本低于13,或者需要其他版本的UUID) b. 创建表时,将主键列的类型设置为`UUID`,并设置默认值为生成UUID的函数(如`DEFAULT uuid_generate_v4()`或`DEFAULT gen_random_uuid()`)。 3. 示例表定义: ```sql CREATE TABLE table_name ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- 其他列... ); ``` 4. 在Java中,如果使用Hibernate,可能需要特殊配置来处理UUID类型(引用[4]提到了一些自定义主键生成策略的方法,但这里我们主要关注数据库层面)。 现在,我们将按照用户的要求,详细说明如何在PostgreSQL中使用UUID作为主键。 ### 步骤1:启用UUID支持 在PostgreSQL中,默认可能没有安装生成UUID的扩展。因此,我们需要先安装`uuid-ossp`扩展(除非你使用的是PostgreSQL 13+且只需要随机UUID,则可以使用内置函数而无需扩展)。 ```sql -- 安装uuid-ossp扩展 CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; ``` 注意:扩展名中的连字符要求必须使用双引号括起来。 ### 步骤2:创建表时使用UUID主键 在创建表时,定义一个类型为`UUID`的列,并设置其默认值为一个生成UUID的函数。常用的函数有: - `uuid_generate_v1()`:基于时间戳和MAC地址生成(有顺序性,但可能暴露MAC地址) - `uuid_generate_v4()`:随机生成(最常用,推荐) - `gen_random_uuid()`:PostgreSQL 13+内置的随机UUID生成函数(无需扩展) #### 示例1:使用`uuid_generate_v4()` ```sql CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(255) NOT NULL UNIQUE ); ``` #### 示例2:使用`gen_random_uuid()`(仅PostgreSQL 13+) ```sql CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), username VARCHAR(50) NOT NULL UNIQUE, email VARCHAR(255) NOT NULL UNIQUE ); ``` ### 步骤3:插入数据 当向表中插入数据时,不需要为主键列提供值,因为数据库会自动生成UUID。 ```sql INSERT INTO users (username, email) VALUES ('john_doe', 'john@example.com'), ('jane_smith', 'jane@example.com'); ``` ### 步骤4:查询数据 查询时,UUID主键会显示为标准格式的UUID字符串(如`a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11`)。 ```sql SELECT * FROM users; ``` ### 注意事项 1. **性能**:UUID作为主键可能会导致索引碎片化,因为UUID是随机的(特别是使用v4或随机生成时)。相比于自增整数,插入性能可能会略有下降,但它在分布式系统中具有优势。 2. **存储空间**:UUID占用16字节,而整数类型通常为4或8字节。因此,在存储和索引空间上,UUID会占用更多空间。 3. **安全性**:随机UUID(v4)不包含可预测的信息,因此更安全。而v1可能包含MAC地址和时间戳,在某些情况下可能泄露信息。 4. **扩展依赖**:如果使用`uuid-ossp`扩展,在迁移数据库时需要确保目标数据库也安装了该扩展。而`gen_random_uuid()`是内置的,无需额外扩展。 ### 在应用程序中处理UUID 在应用程序中,你可以将UUID作为字符串处理。例如,在Java中,可以使用`java.util.UUID`类型。在Hibernate中,可以这样映射: ```java import org.hibernate.annotations.Type; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import java.util.UUID; @Entity public class User { @Id @GeneratedValue @Type(type = "org.hibernate.type.PostgresUUIDType") private UUID id; // 其他字段... } ``` 或者,如果你使用JPA 2.1及以上,可以这样: ```java @Entity public class User { @Id @GeneratedValue @Column(columnDefinition = "UUID") private UUID id; // 其他字段... } ``` ### 总结 使用UUID作为主键在分布式系统中非常有用,可以避免主键冲突。在PostgreSQL中,通过安装扩展或使用内置函数(13+版本)可以方便地生成UUID。创建表时将主键列设置为`UUID`类型并指定默认值即可。 §§相关问题§§ 1. 如何在PostgreSQL 13+中不使用扩展生成随机UUID? 2. 使用UUID作为主键有哪些优缺点? 3. 在分布式系统中,使用UUID作为主键有什么优势? 4. 如何将现有的整数主键表迁移到UUID主键? 5. PostgreSQL中如何生成其他版本的UUID(如版本1)?</think>### PostgreSQL 使用 UUID 作为主键详解 #### 1. 启用 UUID 支持 在 PostgreSQL 中使用 UUID 需要先安装扩展: ```sql -- 安装 uuid-ossp 扩展(支持所有版本) CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- PostgreSQL 13+ 可使用内置函数 SELECT gen_random_uuid(); -- 无需安装扩展[^1][^3] ``` #### 2. 创建使用 UUID 主键的表 ```sql CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT uuid_generate_v4(), -- 随机UUID name VARCHAR(50) NOT NULL, email VARCHAR(100) UNIQUE ); -- 或使用 PostgreSQL 13+ 的内置函数 CREATE TABLE products ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), -- 随机UUID(无需扩展) product_name VARCHAR(100) )[^5][^1]; ``` #### 3. 插入数据(自动生成 UUID) ```sql -- 不指定 id 列,自动生成 UUID INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com'), ('李四', 'lisi@example.com'); -- 显式插入 UUID INSERT INTO users (id, name) VALUES (uuid_generate_v1(), '王五'); -- 基于时间戳的UUID[^2] ``` #### 4. 查询 UUID 数据 ```sql SELECT * FROM users WHERE id = 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'; -- 获取最后插入的UUID INSERT INTO users (name) VALUES ('赵六') RETURNING id; ``` #### 5. UUID 版本说明 | 版本 | 生成函数 | 特点 | |------|-------------------|-------------------------------| | v1 | `uuid_generate_v1` | 基于时间戳+MAC地址,有顺序性 | | v4 | `uuid_generate_v4` | 完全随机 (推荐) | | v4 | `gen_random_uuid` | PostgreSQL 13+ 内置随机UUID | #### 6. 性能优化建议 1. **索引优化**:UUID 作为主键会自动创建索引 2. **存储空间**:UUID 占用 16 字节,比 BIGINT(8字节) 更大 3. **插入性能**:随机 UUID 可能导致索引碎片,建议: ```sql CREATE TABLE logs ( id UUID PRIMARY KEY DEFAULT uuid_generate_v1() -- 有序UUID减少碎片 )[^1]; ``` #### 7. 应用层集成示例(Java/Hibernate) ```java @Entity public class User { @Id @GeneratedValue(generator = "UUID") @GenericGenerator( name = "UUID", strategy = "org.hibernate.id.UUIDGenerator" ) @Column(columnDefinition = "UUID") private UUID id; // ... }[^4] ``` #### 8. 迁移现有表到 UUID ```sql -- 步骤1:添加 UUID 列 ALTER TABLE employees ADD COLUMN uuid_id UUID DEFAULT uuid_generate_v4(); -- 步骤2:更新主键 ALTER TABLE employees DROP CONSTRAINT employees_pkey, ADD PRIMARY KEY (uuid_id); -- 步骤3:删除旧ID列(可选) ALTER TABLE employees DROP COLUMN old_id; ``` > **最佳实践**: > - 分布式系统首选 UUID v4 > - 单机系统可考虑 UUID v1 减少索引碎片 > - PostgreSQL 13+ 优先使用 `gen_random_uuid()`[^1]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值