通用唯一标识符(UUID)是用于在计算机系统中唯一标识信息的128位数字。它们对于分布式系统、数据库设计和现代软件架构至关重要。本指南将全面介绍关于UUID的所有知识。

目录

核心要点

  • 通用性:UUID设计为在空间和时间上唯一,无需中央协调。
  • 128位:UUID是128位数字,通常显示为带连字符的32个十六进制字符。
  • 多个版本:UUID v4(随机)最常用;UUID v1(基于时间)适用于排序。
  • 碰撞概率:生成重复UUID v4的概率极低(约2^122分之一)。
  • 数据库主键:UUID非常适合分布式数据库主键。
  • 隐私性:UUID v4不会泄露创建时间或位置信息。

需要快速生成UUID?试试我们支持多种版本和格式的免费在线工具。

立即生成UUID - 免费在线UUID生成器

什么是UUID?

UUID(Universally Unique Identifier,通用唯一标识符),在微软系统中也称为GUID(Globally Unique Identifier,全局唯一标识符),是一个128位的标识符,在所有设备和所有时间上都是唯一的。UUID由RFC 4122标准化,在软件开发中被广泛使用。

UUID的关键特性:

  1. 唯一性:每个UUID几乎可以保证是唯一的
  2. 去中心化:生成UUID不需要中央权威机构
  3. 可移植性:UUID可以在任何系统上生成,无需协调

UUID结构和格式

UUID通常表示为32个十六进制数字,分成五组,用连字符分隔:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

例如:

550e8400-e29b-41d4-a716-446655440000

结构分解如下:

部分 长度 描述
time_low 8字符 时间的低32位
time_mid 4字符 时间的中16位
time_hi_and_version 4字符 时间的高12位 + 4位版本号
clock_seq_hi_and_reserved 2字符 时钟序列高位 + 变体
clock_seq_low 2字符 时钟序列低位
node 12字符 48位节点标识符

M位置表示UUID版本(1-5),N位置表示变体(RFC 4122 UUID通常为8、9、a或b)。

UUID版本详解

UUID v1(基于时间)

UUID v1使用当前时间戳和计算机的MAC地址生成。

结构:

  • 60位时间戳(自1582年10月15日以来的100纳秒间隔)
  • 14位时钟序列(处理时钟调整)
  • 48位节点ID(通常是MAC地址)

优点:

  • 可按创建时间排序
  • 在单台机器上保证唯一性
  • 可以提取创建时间戳

缺点:

  • 泄露MAC地址(隐私问题)
  • 泄露创建时间
  • 需要访问MAC地址

示例:

6ba7b810-9dad-11d1-80b4-00c04fd430c8
         ^
         版本1

UUID v4(随机)

UUID v4使用随机或伪随机数生成。这是最常用的版本。

结构:

  • 122个随机位
  • 4位用于版本(0100)
  • 2位用于变体(10)

优点:

  • 生成简单
  • 无隐私问题
  • 无硬件依赖
  • 适用于任何环境

缺点:

  • 不能按时间排序
  • 碰撞概率略高(但仍可忽略不计)

示例:

f47ac10b-58cc-4372-a567-0e02b2c3d479
              ^
              版本4

其他UUID版本

版本 名称 描述
v2 DCE安全 很少使用,包含POSIX UID/GID
v3 基于名称(MD5) 使用MD5从命名空间+名称生成
v5 基于名称(SHA-1) 使用SHA-1从命名空间+名称生成
Nil 空UUID 全零:00000000-0000-0000-0000-000000000000

代码示例

JavaScript

// 使用 crypto.randomUUID()(现代浏览器和Node.js 14.17+)
const uuid = crypto.randomUUID();
console.log(uuid); // 例如:"f47ac10b-58cc-4372-a567-0e02b2c3d479"

// 手动生成UUID v4(兼容方案)
function generateUUIDv4() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
    const r = Math.random() * 16 | 0;
    const v = c === 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

// 使用uuid库
// npm install uuid
import { v4 as uuidv4, v1 as uuidv1 } from 'uuid';

const randomUUID = uuidv4();  // 随机UUID
const timeUUID = uuidv1();    // 基于时间的UUID

Python

import uuid

# 生成UUID v4(随机)
random_uuid = uuid.uuid4()
print(random_uuid)  # 例如:f47ac10b-58cc-4372-a567-0e02b2c3d479

# 生成UUID v1(基于时间)
time_uuid = uuid.uuid1()
print(time_uuid)

# 生成UUID v5(基于名称,使用SHA-1)
namespace = uuid.NAMESPACE_DNS
name_uuid = uuid.uuid5(namespace, 'example.com')
print(name_uuid)

# 转换为不同格式
uuid_str = str(random_uuid)           # 字符串格式
uuid_hex = random_uuid.hex            # 无连字符
uuid_bytes = random_uuid.bytes        # 16字节
uuid_int = random_uuid.int            # 128位整数

Java

import java.util.UUID;

public class UUIDExample {
    public static void main(String[] args) {
        // 生成UUID v4(随机)
        UUID randomUUID = UUID.randomUUID();
        System.out.println(randomUUID);
        
        // 从字符串解析UUID
        UUID parsedUUID = UUID.fromString("550e8400-e29b-41d4-a716-446655440000");
        
        // 获取UUID组件
        long mostSigBits = randomUUID.getMostSignificantBits();
        long leastSigBits = randomUUID.getLeastSignificantBits();
        int version = randomUUID.version();  // v4返回4
        int variant = randomUUID.variant();  // RFC 4122返回2
        
        // 转换为无连字符的字符串
        String uuidWithoutHyphens = randomUUID.toString().replace("-", "");
    }
}

UUID最佳实践

1. 选择正确的版本

使用场景 推荐版本
通用用途 UUID v4
需要时间排序 UUID v1 或 ULID
确定性生成 UUID v5
隐私敏感 UUID v4

2. 数据库考虑

-- PostgreSQL:使用原生UUID类型
CREATE TABLE users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    name VARCHAR(100)
);

-- MySQL:使用BINARY(16)以获得更好的性能
CREATE TABLE users (
    id BINARY(16) PRIMARY KEY,
    name VARCHAR(100)
);

3. 性能技巧

  • 谨慎索引:UUID索引可能很大;考虑使用部分索引
  • 使用二进制存储:存储为BINARY(16)而不是VARCHAR(36)
  • 考虑替代方案:对于高性能需求,考虑ULID或Snowflake ID

4. 安全考虑

  • 不要单独使用UUID作为安全令牌
  • UUID v1会泄露时间戳和MAC地址
  • 使用安全生成器时,UUID v4是加密随机的

常见使用场景

  1. 数据库主键

    • 无需协调的分布式数据库
    • 合并来自多个来源的数据
    • 避免顺序ID猜测
  2. 会话标识符

    • Web会话令牌
    • API请求关联ID
  3. 文件和资源命名

    • 上传的文件名
    • 临时文件标识符
  4. 分布式系统

    • 消息队列标识符
    • 微服务请求追踪
    • 事件溯源
  5. API设计

    • REST API中的资源标识符
    • 幂等性键

常见问题

UUID碰撞的概率是多少?

对于UUID v4,碰撞概率约为2^122分之一(约5.3 x 10^36)。要有50%的碰撞概率,你需要生成约2.71万亿亿个UUID。在实际应用中,UUID碰撞几乎是不可能的。

应该使用UUID v1还是v4?

大多数应用推荐使用UUID v4,因为它简单且保护隐私。只有在需要基于时间排序或需要提取创建时间戳时才使用UUID v1

UUID适合作为数据库主键吗?

是的,UUID非常适合分布式数据库。但需要考虑以下权衡:

  • 优点:无需协调、全局唯一、适合分片
  • 缺点:比整数大(16字节 vs 4-8字节)、随机UUID可能导致索引碎片

如何不写代码生成UUID?

你可以使用在线工具,如我们的免费UUID生成器,无需编写任何代码即可快速生成各种格式的UUID。

UUID和GUID有什么区别?

UUID和GUID本质上是同一个东西。GUID(Globally Unique Identifier,全局唯一标识符)是微软对UUID的称呼。两者都遵循相同的RFC 4122标准。

总结

UUID是现代软件开发中的基础工具,提供了一种无需中央协调即可生成唯一标识符的可靠方法。了解不同版本及其权衡有助于你为特定用例做出明智的决策。

快速总结:

  • 大多数通用应用使用UUID v4
  • 需要基于时间排序时使用UUID v1
  • 需要确定性、可重复的标识符时使用UUID v5
  • 数据库使用时考虑存储格式和索引策略

准备好生成UUID了吗?试试我们的免费在线工具:

立即生成UUID - 免费在线UUID生成器