1. 主页 > 世界杯新浪 >

UUID 是什么

UUID(通用唯一标识符) 就是一个全宇宙唯一的 ID,常用来标识用户、订单、设备、会话等。

🧊 举个现实生活中的例子

比如你去医院挂号,每个人都有一个唯一的挂号编号。

你去银行开账户,每个账户也有个唯一的编号。

那在编程世界里,如果你想标识一个用户或订单,并且不想依赖数据库的自增主键怎么办?

你就用 UUID!因为它能保证唯一性,不会重复。

👀 UUID 看起来像什么?

一个标准的 UUID 长这样:

550e8400-e29b-41d4-a716-446655440000

这是 36 个字符(包含 4 个 -),由 128 位(16 字节)的数据组成。

格式结构如下:

xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx

M 表示 UUID 的版本(最常用的是 v4)N 表示变体

🧪 UUID 有哪些版本?

UUID 有很多版本,最常见的是:

版本名称特点v1基于时间戳包含 MAC 地址 + 当前时间v3/v5基于名字可重复(名字 + 命名空间 hash)✅ v4基于随机数最常用,完全随机,适合通用生成比如:

from uuid import uuid4

print(uuid4()) # 随机生成一个 v4 UUID

输出类似:

e21f1c68-18f9-4728-a364-278195fd61ae

🔐 UUID 为什么说“几乎不可能重复”?

因为它有 2 的 128 次方种组合(约等于 3.4 × 10^38)

就算你每秒生成 10 亿个 UUID,连续生成 100 年,也不太可能碰撞。

✅ UUID 在实际项目中的用途:

场景用法说明用户 ID不用数据库自增,提前生成 UID订单号 / 交易号确保唯一,适合分布式系统文件命名上传文件时用 UUID 防止重名冲突会话 / token ID标识用户会话

📌 UUID vs 数据库自增 ID 的区别?

特点UUID数据库自增 ID唯一性全局唯一(跨系统不重复)只在一个库唯一安全性不容易猜测可以被预测顺序性不连续,不适合做排序/索引优化是连续的数字使用场景分布式、需要提前生成的 ID单库、简单系统

🧪 Python 中怎么用 UUID?

from uuid import uuid4

user_id = uuid4()

print(user_id) # 输出一个随机 UUID

print(user_id.bytes) # 输出 16 字节二进制形式

✅ 总结一句话:

UUID 是一种在全球范围内都唯一的标识符,常用于分布式系统、用户 ID、订单号等,不依赖数据库自增,非常适合需要“唯一性 + 不重复”的场景。

MongoDB能直接存储UUID么?

MongoDB 不是不能存储 UUID,而是它内部没有专门的 UUID 类型,只能用 Binary(二进制)格式来存储 UUID。

这就好比:

UUID 是个「身份证号」,但 MongoDB 的抽屉里没有专门的「身份证类型」,只能当「字节流」装进去。

🔍 更详细的解释:

✅ UUID 是什么?

UUID 是一种 128 位(16 字节)长度的唯一标识符:

import uuid

print(uuid.uuid4())

# 输出:3fa85f64-5717-4562-b3fc-2c963f66afa6

它的本质是 16 个字节的二进制数据。

❓为什么 MongoDB 不能直接存 UUID?

因为 MongoDB 的 BSON 数据格式没有一个专门叫 UUID 的字段类型。

它只能识别以下几种:

类型说明String普通字符串Int32/Int64整数Boolean布尔值Binary二进制数据(支持 UUID)Date日期所以,MongoDB 会用 Binary subtype 4(也叫 UUID 子类型)来保存 UUID。

🧩 举个例子:

假设我们生成了一个 UUID:

uuid_val = uuid.uuid4()

# 例如:'3fa85f64-5717-4562-b3fc-2c963f66afa6'

我们不能直接丢进 MongoDB,必须先转换成 Binary:

from bson.binary import Binary, UuidRepresentation

binary_data = Binary.from_uuid(uuid_val, uuid_representation=UuidRepresentation.STANDARD)

这样才能被 MongoDB 正确识别为 UUID。

✅ MongoDB 怎么识别这是 UUID?

它通过 Binary 类型的 子类型(subtype) 来识别。

Subtype 值含义0x00普通 Binary 数据0x04UUID 标准表示(推荐)也就是说,UUID 在 MongoDB 里是 Binary 类型,但有一个特殊的 subtype,告诉数据库「这是 UUID」而不是纯二进制。

🔁 为什么读出来还要 .as_uuid()?

因为你存进去的是 Binary 对象,读取出来后是 Binary 类型,要还原成 uuid.UUID 对象,就需要:

uuid_val = binary_data.as_uuid()

就像你从冰箱里拿出一袋速冻水饺,还得煮一下才能吃。😄

🧵 总结:

问题回答MongoDB 能不能存 UUID?能,但它会存成 Binary 类型(subtype = 4)为什么不用字符串?可以用字符串,但 Binary 更节省空间(16字节 vs 36 字符)如何保存 UUID?用 Binary.from_uuid() 转换如何还原 UUID?用 binary_val.as_uuid()

再用一个完整例子来说明MongoDB 中没有直接的 UUID 类型,过程如下 :

✅ 生成 UUID

✅ 保存进 MongoDB(以二进制 Binary 格式)

✅ 从 MongoDB 读出并还原为 UUID 对象

我们会用到:

Python 内置模块:uuidMongoDB 驱动:pymongoBinary 类型支持:bson.binary.Binary

🧪 代码示例:保存和读取 UUID

from uuid import uuid4, UUID

from pymongo import MongoClient

from bson.binary import Binary, UuidRepresentation

import bson

# 🔌 连接 MongoDB

client = MongoClient("mongodb://localhost:27017")

db = client["demo_db"]

collection = db["users"]

# ✅ 模拟用户数据(生成 UUID)

user_uuid = uuid4()

print(f"原始 UUID: {user_uuid}")

# 👇 保存到 MongoDB,转成 Binary 格式

user_doc = {

"user_id": Binary.from_uuid(user_uuid, uuid_representation=UuidRepresentation.STANDARD),

"name": "张三"

}

collection.insert_one(user_doc)

# 🔍 从 MongoDB 查询出来

retrieved = collection.find_one({"name": "张三"})

# 👇 还原成 UUID 对象

stored_binary: Binary = retrieved["user_id"]

uuid_restored: UUID = stored_binary.as_uuid()

print(f"还原出来的 UUID: {uuid_restored}")

print("是否相等:", uuid_restored == user_uuid)

✅ 输出示例

原始 UUID: d5ecde7d-c1e5-42b3-8f1a-62ea5edb71e2

还原出来的 UUID: d5ecde7d-c1e5-42b3-8f1a-62ea5edb71e2

是否相等: True

🧠 为什么要 Binary.from_uuid() 和 as_uuid()?

MongoDB 中没有直接的 UUID 类型,它会存成 二进制的 16 字节数据(Binary)。

所以:

操作方法UUID → BinaryBinary.from_uuid(uuid)Binary → UUIDbinary_value.as_uuid()这就跟把“身份证号”压缩存入数据库,取出来后再“还原成人”的过程一样。

📌 小贴士:uuid_representation 参数

你可能注意到这一段 👇:

uuid_representation=UuidRepresentation.STANDARD

这个是 PyMongo 4.x 要求明确指定的 UUID 存储格式。推荐用 STANDARD,符合 RFC 4122 标准。