最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
SQL插入数据时怎样动态生成全局唯一标识符
时间:2026-07-11 09:57:47 编辑:袖梨 来源:一聚教程网
数据库原生UUID生成最稳,但需按数据库选函数:MySQL用UUID()配CHAR(36),SQL Server用NEWID()或NEWSEQUENTIALID()配UNIQUEIDENTIFIER,PostgreSQL优先用pgcrypto的gen_random_uuid()配UUID,跨库须抽象方言或应用层生成。
直接用数据库原生函数最稳,别自己拼字符串或依赖应用层生成——除非你明确需要跨库一致性或特殊格式。
MySQL 8.0+ 用 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') - 别在 WHERE 条件里用
UUID()做等值匹配——它每次调用都不同,WHERE id = UUID()永远不成立 - 性能注意:UUID 无序,作为聚簇主键会导致频繁页分裂,高并发写入时建议搭配
INNODB的ROW_FORMAT=COMPRESSED或改用自增 ID + 单独加唯一索引
SQL Server 必须用 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却不设默认值或不显式插入——否则插入失败 - 如果要用短 ID(如
UID12345678),得靠计算字段或触发器,但NEWID()本身不支持截取后设默认值(函数有副作用,不能在列定义里用)
PostgreSQL 要先装扩展,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 走天下。