SQL插入数据时动态生成全局唯一标识符

作者:技术拾光

时间:2026-07-20

浏览:461

不同数据库的UUID生成函数互不相同:MySQL使用UUID()并配合CHAR(36)类型,SQLServer采用NEWID()或NEWSEQUENTIALID(),PostgreSQL建议选用pgcrypto扩展中的gen_random_uuid()。在跨数据库应用环境下,应当设计一个方言适配层,或者在应用层统一生成UUID值,避免在SQL语句中硬编码具体

文章目录

数据库原生UUID生成,确实是最稳妥的方案,前提是选对数据库对应的函数。MySQL用UUID()配合CHAR(36),SQL Server用NEWID()或NEWSEQUENTIALID()配合UNIQUEIDENTIFIER,PostgreSQL优先用pgcrypto扩展的gen_random_uuid()配合UUID类型。跨库场景下,要么抽象出方言适配层,要么在应用层统一生成——别指望一条SQL打通所有数据库。

SQL插入数据时动态生成全局唯一标识符

直接调用数据库原生函数是性价比最高的做法,没必要自己拼字符串或依赖应用层生成——除非你明确需要跨库一致性,或者对ID格式有特殊要求。

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,无序;如果需要时间有序的UUID,得用第三方扩展如 pg_uuidv7,不在原生范围内

真正容易被忽略的点是:跨数据库迁移脚本时,UUID()、NEWID()、gen_random_uuid() 三者语法不兼容,硬编码函数名等于埋雷。如果项目要支持多库,要么统一用应用层生成(比如 Python 的 uuid.uuid4().hex),要么抽象出方言适配层,别指望一条 SQL 走天下。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章