MySQL:如何仅在userId+tokenValue无重复时插入数据?
解决方案
首先,你需要先给firebaseTokens表的userId和tokenValue列创建联合唯一约束——这是从根源防止重复行的基础,还能避免并发插入场景下出现重复数据的问题:
ALTER TABLE firebaseTokens ADD CONSTRAINT unique_user_token UNIQUE (userId, tokenValue);
接下来根据你使用的数据库类型,选择对应的插入语法:
1. MySQL/MariaDB
方式一:INSERT IGNORE
遇到重复的联合键时直接忽略插入操作,不会抛出错误:
INSERT IGNORE INTO firebaseTokens (userId, tokenValue) VALUES (11, '123456');
方式二:INSERT ... ON DUPLICATE KEY
如果需要明确执行“无操作”(兼容旧版本MySQL),可以写空更新逻辑:
INSERT INTO firebaseTokens (userId, tokenValue) VALUES (11, '123456') ON DUPLICATE KEY UPDATE userId = userId; -- 空操作,不会修改任何数据
MySQL 8.0.19及以上版本支持更简洁的写法:
INSERT INTO firebaseTokens (userId, tokenValue) VALUES (11, '123456') ON DUPLICATE KEY DO NOTHING;
2. PostgreSQL
使用ON CONFLICT子句直接指定冲突时不执行任何操作:
INSERT INTO firebaseTokens (userId, tokenValue) VALUES (11, '123456') ON CONFLICT (userId, tokenValue) DO NOTHING;
3. SQL Server
方式一:MERGE语句
MERGE INTO firebaseTokens AS target USING (VALUES (11, '123456')) AS source (userId, tokenValue) ON target.userId = source.userId AND target.tokenValue = source.tokenValue WHEN NOT MATCHED THEN INSERT (userId, tokenValue) VALUES (source.userId, source.tokenValue);
方式二:INSERT ... WHERE NOT EXISTS
(注意:高并发场景下建议配合联合唯一约束使用,避免重复插入)
INSERT INTO firebaseTokens (userId, tokenValue) SELECT 11, '123456' WHERE NOT EXISTS ( SELECT 1 FROM firebaseTokens WHERE userId = 11 AND tokenValue = '123456' );
内容的提问来源于stack exchange,提问作者alphatango165
相关产品推荐
相关产品推荐

