数据库原生UUID生成最稳,但需按数据库选函数:MySQL用UUID()配CHAR(36),SQL Server用NEWID()或NEWSEQUENTIALID()配UNIQUEIDENTIFIER,PostgreSQL优先用pgcrypto的gen_random_uuid()配UUID,跨库须抽象方言或应用层生成。
直接用数据库原生函数最稳,别自己拼字符串或依赖应用层生成——除非你明确需要跨库一致性或特殊格式。
UUID(),但字段类型和长度得配对UUID() 返回的是 36 字符的带连字符字符串(如 550e8400-e29b-41d4-a716-446655440000),不是二进制。如果建表时用了 CHAR(36) 或 VARCHAR(36),能存下;但用 CHAR(32) 会截断连字符,导致数据损坏。
id CHAR(36) DEFAULT UUID() PRIMARY KEY
INSERT INTO users (name) VALUES ('Alice')
UUID() 做等值匹配——它每次调用都不同,WHERE id = UUID() 永远不成立INNODB 的 ROW_FORMAT=COMPRESSED 或改用自增 ID + 单独加唯一索引NEWID() 或 NEWSEQUENTIALID(),不能混用NEWID() 是随机 GUID,NEWSEQUENTIALID() 是递增 GUID,二者行为差异极大,且 NEWSEQUENTIALID() 只能用于列默认值,不能出现在 INSERT 或 SELECT 表达式中。
id UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY
DEFAULT NEWSEQUENTIALID(),但注意它不能在 INSERT ... VALUES (NEWSEQUENTIALID(), ...) 中直接调用,会报错 Invalid use of 'NEWSEQUENTIALID'
UNIQUEIDENTIFIER 字段设成 NOT NULL 却不设默认值或不显式插入——否则插入失败UID12345678),得靠计算字段或触发器,但 NEWID() 本身不支持截取后设默认值(函数有副作用,不能在列定义里用)gen_random_uuid() 才可用PostgreSQL 默认不提供 UUID 生成函数。uuid-ossp 需要超级用户权限启用,CI 环境常卡住;pgcrypto 更轻量,普通用户也能装,推荐优先用它。
CREATE EXTENSION IF NOT EXISTS "pgcrypto"
id UUID DEFAULT gen_random_uuid() PRIMARY KEY
INSERT INTO users (name) VALUES ('Bob'),自动填充uuid_generate_v4() —— 它属于 uuid-ossp,没装扩展会报错 function uuid_generate_v4() does not exist
gen_random_uuid() 生成的是 RFC 4122 v4 UUID,无序;如需时间有序,得用第三方扩展如 pg_uuidv7,不在原生范围内真正容易被忽略的点是:跨数据库迁移脚本时,UUID()、NEWID()、gen_random_uuid() 三者语法不兼容,硬编码函数名等于埋雷。如果项目要支持多库,要么统一用应用层生成(比如 Python 的 uuid.uuid4().hex),要么抽象出方言适配层,别指望一条 SQL 走天下。