SQL去重防止重复写入_SQL约束与逻辑结合使用

admin 百科 12
防重核心是写入前拦截,首选唯一约束保底线,辅以ON DUPLICATE KEY UPDATE或INSERT ON CONFLICT等原子语句,配合幂等键校验,避免先查后插引发的竞态问题。

SQL去重防止重复写入_SQL约束与逻辑结合使用-第1张图片-佛山资讯网

防止重复写入,核心不是只靠SQL去重语句(如 DISTINCT 或 GROUP BY),而是要在数据写入前就拦住重复——靠约束保底线,靠逻辑控流程。

用唯一约束(UNIQUE)锁死重复入口

这是最直接、最可靠的防重手段。在业务上天然不能重复的字段组合(如手机号、订单号、用户+日期组合)上建唯一索引或唯一约束,数据库会在 INSERT/UPDATE 时自动拒绝违反约束的操作。

  • 建表时加:`CREATE TABLE user_log (user_id INT, log_date DATE, UNIQUE(user_id, log_date));`
  • 已有表加:`ALTER TABLE user_log ADD CONSTRAINT uk_user_date UNIQUE (user_id, log_date);`
  • 插入时捕获异常(如 MySQL 的 1062 错误码),程序中友好提示“该记录已存在”,而不是让报错穿透到前端

INSERT ... ON DUPLICATE KEY UPDATE(MySQL)或 MERGE(SQL Server/PostgreSQL)

当需要“有则更新、无则插入”时,用这类原子语句替代先查后插的逻辑,避免竞态条件(两个请求同时查不到、同时插入成功)。

  • MySQL 示例:`INSERT INTO user_points (uid, points) VALUES (123, 10) ON DUPLICATE KEY UPDATE points = points + 10;`(前提是 uid 或组合有唯一约束)
  • PostgreSQL 推荐用 `INSERT ... ON CONFLICT DO UPDATE`,语义更清晰,支持 WHERE 条件过滤更新范围
  • 注意:这类语句依赖唯一约束触发冲突判断,没约束就退化为普通插入,起不到防重作用

应用层加幂等标识 + 数据库校验

对无法强约束的场景(如异步消息、第三方回调),由调用方提供幂等键(如 request_id、trace_id),写入前先查该 ID 是否已处理。

标签: mysql redis 前端 ai red

发布评论 0条评论)

还木有评论哦,快来抢沙发吧~