MySQL原生支持UUID()函数,返回36字符标准UUID字符串,无需插件;PostgreSQL需启用pgcrypto扩展才能使用gen_random_uuid();SQLite无真正UUID支持,hex(randomblob(16))仅是伪UUID。

MySQL里没有UUID()函数返回带横线的字符串,但能直接用
MySQL原生支持UUID()函数,每次调用生成一个标准格式的UUID(如 '6f1c5e9a-8b2d-4e7c-b0a1-3d9e8f7a1b2c'),它不是存储函数,不依赖插件或配置。你不需要额外安装,只要版本 ≥ 5.0 就能用。
常见错误是以为它返回二进制或需要手动拼接——其实它就是字符串,直接INSERT INTO t(id) VALUES (UUID())完全合法。
- 它生成的是 UTF-8 字符串,长度固定为 36 个字符(32 位十六进制 + 4 个横线)
- 性能上比自增ID略低,因为无序、不可预测,会导致二级索引页分裂更频繁
- 如果表主键是
CHAR(36),别用VARCHAR(36)——前者定长,InnoDB 更省心
PostgreSQL用gen_random_uuid()前得先启用pgcrypto扩展
PostgreSQL默认不提供UUID()函数,真正常用的是gen_random_uuid(),但它属于pgcrypto扩展,必须手动启用,否则会报错:function gen_random_uuid() does not exist。
启用只需一条命令:CREATE EXTENSION IF NOT EXISTS "pgcrypto";,注意双引号不能少,因为扩展名含下划线。
- 该函数返回的是
uuid类型(非字符串),原生支持索引和比较,比存成TEXT更高效 - 不用
md5(random()::text)之类土法生成——既不随机也不符合UUID v4规范 - 如果已用
TEXT列存了带横线的UUID,想转成uuid类型:先ALTER TABLE t ALTER COLUMN id TYPE uuid USING id::uuid;
去掉UUID里的横线:MySQL用REPLACE,PostgreSQL用replace()或::text转换
有些场景(比如做短链ID、日志追踪码)要求纯32位十六进制字符串,横线纯属冗余。去横线不是“优化”,而是字段语义需求——你存的就是32字节hex,不该混入分隔符。
MySQL最简写法:REPLACE(UUID(), '-', '');PostgreSQL对应是replace(gen_random_uuid()::text, '-', '')。
- 别在应用层拼接后再入库——数据库层生成+清理更原子,避免应用重启/异常导致不一致
- PostgreSQL中
uuid类型不能直接||拼接字符串,必须先转::text,否则报operator does not exist: uuid || text - 如果后续要用这32位字符串做
IN查询,确保所有输入都统一去横线,否则'abc123...' != 'ab-c1-23...'
SQLite没内置UUID函数,别硬套,用hex(randomblob(16))凑合但要注意缺陷
SQLite真没有UUID(),也没有扩展机制。网上流传的hex(randomblob(16))只是生成32位随机hex,不符合UUID v4结构(缺少版本位和变体位),严格说不算UUID,只是“看起来像”的随机ID。
如果你只是要唯一性且不与其他系统交互,它够用;但若需和MySQL/PostgreSQL交换UUID,或对接OpenAPI规范,这个就不可互认。
- 它不保证全局唯一,只保证单库高概率不重复;并发插入时碰撞风险略高于标准UUID
- 无法用
sqlite3_bind_text安全传入带横线的UUID字符串——因为没类型校验,全靠应用层守规矩 - 真要兼容标准UUID,建议在应用层生成(比如Python用
uuid.uuid4().hex),别让SQLite背锅
UUID去横线这事本身简单,难的是选对生成源头:数据库生成方便,但跨库一致性得靠规范约束;应用层生成灵活,但得管好时钟、熵源和序列化逻辑。横线留不留,本质是字段契约问题——一旦定下,上下游就得一起守。










