You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Prisma使用MongoDB数据源时创建自增ID的正确方法

Prisma + MongoDB 自增序列实现方案

问题说明

Prisma 对接 MongoDB 数据源时,模型字段配置的autoincrement()默认值函数无法生效,示例模型定义如下:

model User {
  id        String   @id @default(auto()) @map("_id") @db.ObjectId
  sequence  Int      @unique @default(autoincrement()) // 该配置在MongoDB下无法生效
  email     String   @unique
  password  String
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

常规「查询表内最后一条记录取最大序列值+1」的实现存在全表扫描开销,且并发场景下容易出现序列重复,需要更低开销、可在创建记录流程内直接完成序列赋值的实现方式,效果对齐 Mongoose 的自增能力。

实现原理

Prisma 提供的autoincrement()是基于关系型数据库原生的自增列特性封装的,MongoDB 本身没有表级自增字段的原生支持,Mongoose 生态的自增能力本质也是依赖独立的计数器集合做原子自增,该方案在 Prisma 中可直接复用,无额外性能损耗,且能保证并发安全。

具体实现步骤

  • 新增计数器模型
    在schema.prisma中新增独立的Counter模型,用于存储各业务模型的当前自增序列值:
model Counter {
  id    String @id @default(auto()) @map("_id") @db.ObjectId
  model String @unique // 绑定需要自增序列的模型名,例如此处存储"User"
  seq   Int    @default(0) // 存储对应模型的最新序列值
}

模型定义完成后执行prisma generate、prisma db push将结构同步到 MongoDB 实例。

  • 初始化计数器记录
    首次使用前,为User模型插入一条初始计数器数据,seq字段初始值设为0即可。

  • 封装原子创建逻辑
    基于Prisma交互式事务+MongoDB原子更新能力,在创建用户的同一事务内完成序列自增、记录创建操作,全程无全表扫描开销:

async function createUser(userPayload: { email: string; password: string }) {
  return prisma.$transaction(async (tx) => {
    // 原子更新计数器,序列值+1后直接返回最新值
    const updatedCounter = await tx.counter.update({
      where: { model: "User" },
      data: { seq: { increment: 1 } },
    })

    // 使用返回的最新序列值创建用户记录
    const newUser = await tx.user.create({
      data: {
        ...userPayload,
        sequence: updatedCounter.seq,
      },
    })

    return newUser
  })
}

方案优势

  • 性能开销极低:计数器集合的查询、更新都走唯一索引,不存在全表扫描,和关系型数据库原生自增的性能差距可以忽略
  • 并发安全:序列自增是MongoDB层面的原子操作,配合事务保证序列更新和记录创建的原子性,不会出现并发场景下的序列重复、跳号问题
  • 扩展性强:后续需要给其他模型加自增序列时,只需要在Counter集合中插入对应模型的初始记录,复用同一套逻辑即可

注意:不要使用「查询User表最大sequence值+1」的方案,除了全表扫描的性能问题外,并发场景下多个请求会读取到相同的最大值,必须加分布式锁才能避免序列重复,整体性能和可靠性都远低于独立计数器方案。

内容的提问来源于stack exchange,提问作者Danilo Cunha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 14:24:22