PostgreSQL向表中插入多行数据的实现方法 含同邮箱多名称场景
PostgreSQL多行数据插入实现
PostgreSQL原生支持单条INSERT语句插入多行数据,在Node.js中使用pg库操作时,可以动态生成占位符实现批量插入,示例代码如下:
// 定义要插入的多行用户数据 const users = [ { name: 'brianc', email: 'brian.m.carlson@gmail.com' }, { name: 'alice', email: 'alice@example.com' }, { name: 'bob', email: 'bob@example.com' } ] // 动态生成占位符,格式为 ($1,$2), ($3,$4), ... const placeholders = users.map((_, index) => `($${index * 2 + 1}, $${index * 2 + 2})`).join(', ') const text = `INSERT INTO users(name, email) VALUES ${placeholders} RETURNING *` // 把所有参数扁平化为一维数组,和占位符顺序对应 const values = users.flatMap(user => [user.name, user.email]) // 执行查询 client .query(text, values) .then(res => { console.log(res.rows) // 输出所有插入成功的行数据 }) .catch(e => console.error(e.stack))
这种方式比循环执行单行插入性能高很多,而且是原子操作,要么全部插入成功要么全部失败。
多姓名对应同一邮箱的场景处理
根据业务规则不同,有两种常见处理方案:
- 允许同邮箱多姓名:不需要做额外配置,直接按上述多行插入逻辑执行即可,数据库会正常存储所有记录,查询时同邮箱会返回多条对应数据。
- 要求邮箱唯一:
- 先给
users表的email字段加唯一约束:
ALTER TABLE users ADD CONSTRAINT unique_email UNIQUE(email);- 插入时使用PostgreSQL的
ON CONFLICT语法处理冲突:- 冲突时跳过重复数据,仅插入新数据:把INSERT语句修改为
INSERT INTO users(name, email) VALUES ${placeholders} ON CONFLICT (email) DO NOTHING RETURNING *- 冲突时用新数据的姓名覆盖原有记录:把INSERT语句修改为
其中INSERT INTO users(name, email) VALUES ${placeholders} ON CONFLICT (email) DO UPDATE SET name = EXCLUDED.name RETURNING *EXCLUDED指代本次插入语句中原本要写入的冲突行数据。
- 先给
内容的提问来源于stack exchange,提问作者Aerodynamika
相关产品推荐
相关产品推荐

