SQL Server 应用 NEWID() 生成随机 UUID,PostgreSQL/MySQL 8.0+ 分别用 gen_random_uuid() 或 UUID(),三者不可混用;NEWID() 适合主键但引发聚簇索引碎片,gen_random_uuid() 需先启用 pgcrypto 扩展,UUID() 在 MySQL 中为 36 字符字符串且无序,跨库脚本需避免硬编码函数名。

SQL Server 用 NEWID(),PostgreSQL/MySQL 8.0+ 用 gen_random_uuid() 或 UUID(),别混用,否则插入失败或重复。
SQL Server 中用 NEWID() 插入唯一 ID
NEWID() 每次调用都生成新的 GUID(128 位随机值),适合做主键或测试数据标识。但注意它不保证顺序,且作为聚簇索引时会引发页分裂,影响性能。
- 直接在
INSERT中使用:INSERT INTO users (id, name) VALUES (NEWID(), 'test') - 建表时设默认值:
id UNIQUEIDENTIFIER DEFAULT NEWID() PRIMARY KEY - 避免在
ORDER BY中依赖NEWID()排序——它每次计算都不同,SELECT * FROM t ORDER BY NEWID()是随机排序,不是按 ID 排
PostgreSQL 中用 gen_random_uuid() 而非 uuid_generate_v4()
PostgreSQL 默认不带 UUID 生成函数。gen_random_uuid() 来自 pgcrypto 扩展,比 uuid-ossp 的 uuid_generate_v4() 更轻量、无需额外权限配置。
- 先启用扩展:
CREATE EXTENSION IF NOT EXISTS "pgcrypto" - 插入时用:
INSERT INTO users (id, name) VALUES (gen_random_uuid(), 'test') - 如果误装了
uuid-ossp,uuid_generate_v4()也能用,但需超级用户权限启用,CI 环境常失败
MySQL 5.7 只能用字符串模拟,8.0+ 才有原生 UUID()
MySQL 的 UUID() 返回的是 36 字符的字符串(含连字符),不是二进制格式,存储开销大;且它基于时间+MAC+随机数,理论上可预测,不适合安全场景,但测试数据够用。
- MySQL 8.0+ 可直接用:
INSERT INTO users (id, name) VALUES (UUID(), 'test') - MySQL 5.7 没有原生支持,有人用
CONV(FLOOR(RAND() * 99999999999999), 10, 36)拼接,但碰撞概率随数据量上升,万级数据就可能重复 -
UUID()生成的值无法用ORDER BY做时间趋势分析——它不按时间递增,和NEWID()一样是“伪随机”
跨数据库写法兼容性差,测试数据脚本别硬写死函数名
用 NEWID() 的脚本在 PostgreSQL 里报错 function newid() does not exist,用 UUID() 在 SQL Server 里报错 ‘UUID’ is not a recognized built-in function name。自动化测试中尤其容易翻车。
- 方案一:用应用层生成 UUID(如 Python 的
uuid.uuid4()),SQL 只做参数化插入 - 方案二:用 Flyway/Liquibase 等迁移工具的方言语法,例如 Liquibase 的
dbms="postgresql"分支控制 - 最容易被忽略的一点:有些 ORM(如 EF Core)对 GUID 主键默认用 sequential GUID(
NEWSEQUENTIALID()),但该函数不能在INSERT ... SELECT中直接调用,会报错Invalid use of a side-effecting operator

















