如何在Prisma + PostgreSQL中配置使用自定义ID?
Prisma + PostgreSQL 实现自定义语义化ID的三种方案
你可以根据自己的需求选择以下任意一种实现方式:
方案1:应用层生成(最适配你的业务场景)
你需要ID绑定业务语义方便识别,直接在业务代码中生成ID是最简单灵活的选择:
- 修改Prisma Schema,移除默认的cuid生成规则,仅保留主键配置:
id String @id
- 编写业务侧ID生成逻辑,比如针对电影数据,可以提取名称的英文字母/拼音缩写,拼接为「4位前缀+横杠+4位后缀」的格式,比如《低俗小说》英文名Pulp Fiction处理后就可以得到
PULP-FICT。 - 数据入库前先调用
prisma.xxx.findUnique({ where: { id: 生成的ID } })校验是否重复,小体量下查询成本极低,碰到重复的情况加个数字后缀或者重新生成即可。
方案2:PostgreSQL数据库层面生成(无需修改业务代码)
如果不想把ID生成逻辑耦合在应用层,可以通过PG自定义函数实现自动生成:
- 先在PostgreSQL中创建生成自定义ID的函数,示例逻辑如下(可根据你的拼接规则调整):
CREATE OR REPLACE FUNCTION generate_semantic_id(item_name TEXT) RETURNS TEXT AS $$ DECLARE -- 提取名称中所有字母数字,取前4位转大写作为前缀 prefix TEXT := UPPER(SUBSTRING(REGEXP_REPLACE(item_name, '[^a-zA-Z0-9]', '', 'g'), 1, 4)); -- 取名称末尾4位字母数字转大写作为后缀 suffix TEXT := UPPER(RIGHT(REGEXP_REPLACE(item_name, '[^a-zA-Z0-9]', '', 'g'), 4)); BEGIN RETURN prefix || '-' || suffix; END; $$ LANGUAGE plpgsql;
- 修改Prisma Schema,通过
dbgenerated调用上面的函数作为ID默认值:
id String @id @default(dbgenerated("generate_semantic_id(name)"))
注意该方案如果生成重复ID会直接抛出入库错误,需要额外编写PG触发器处理冲突,适合数据量极小、重复概率极低的场景。
方案3:无侵入混合方案(改造成本最低)
如果你只有部分数据需要自定义语义ID,剩下的还是可以用默认cuid,不需要修改原有主键的默认配置:
id String @id @default(cuid())
插入需要自定义ID的数据时,直接手动传入你生成好的ID(比如PULP-FICT)即可,Prisma会优先使用你传入的ID,没有传的情况下才会自动生成cuid,完全不需要改动原有逻辑。
内容的提问来源于stack exchange,提问作者antonwilhelm
相关产品推荐
相关产品推荐

