mysql - MySQL 语句 ON DUPLICATE KEY 用于非键
问题描述
我正在开发一款游戏,它要求用户(主要是孩子)将前缀和后缀组合成一个唯一的用户名,比如 BlueBaron。现在只有这么多的前缀和后缀,所以如果用户生成一个现有的,则会在其上附加一个数字,例如 BlueBaron2。
我有一张如下表:
| id | prefix_id | suffix_id | identifier_index | username | hashbrown | salt | coins | ranking | date_created | date_updated
是一个自动递增的id
、唯一的、非空的主键——我假设对于这个特定的实例,我实际上不需要担心id
. prefix_id
andsuffix_id
不为空,但因为它们引用公共前缀和后缀,所以它们不是唯一的。其余的行只是非空值。
理想情况下,我想检查一个新用户是否与另一个用户完全相同prefix_id
,suffix_id
并增加identifier_index
.
我用多个(SELECT 然后 INSERT)语句尝试了这个,但我担心数据可能不会更新/唯一(另一个用户可能在您插入的时间之间插入,等等)。
这可能在单个插入语句中吗?我读过,ON DUPLICATE KEY
但我不确定这是否适用于此。
更新:
但是,identifier_index
即使 prefix_id 和 suffix_id 不同,也会增加。在最后一个条目的情况下,根本不会增加导致重复条目错误:
解决方案
这是个好问题。我不是开发人员,但从数据库管理员的角度来看,我会说你需要这样做。
您肯定需要一个跨越 3 列的唯一索引。
CREATE TABLE `a` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`prefix_id` varchar(10) NOT NULL,
`suffix_id` varchar(10) NOT NULL,
`identifier_index` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uidx_psi` (`prefix_id`,`suffix_id`,`identifier_index`)
) ENGINE=InnoDB;
这是必须的,你要保证数据的完整性!
您的插入语句如下所示:
insert into a (prefix_id, suffix_id, identifier_index)
select 'asdf', 'qwer', coalesce(max(identifier_index) + 1, 1)
from a
where prefix_id = 'asdf' and suffix_id = 'qwer';
但请注意,您可能会遇到死锁问题。当另一个事务在此查询仍在运行时尝试插入时,就会发生这种情况。不过,死锁并不是什么严重的问题。通常,应用程序以某种方式构建,它只是再次尝试,直到插入成功。
推荐阅读
- postgresql - 带有 docker compose 的 postgres 给出了 FATAL: role "root" does not exist 错误
- excel - 从数组到工作表的数据
- stripe-payments - Stripe Proration - 预付费用?
- javascript - 测试 session.cookie_httponly .htaccess
- r - 如何拆分此对象并将其元素作为单个对象插入到列表中?R
- delphi - 仅 Indy 出现 SSL 错误,不会发生 HTTPRIO
- java - 2个大列表之间的列表比较
- java - 在 Java 中不使用类型(类名)创建新实例
- c++ - 同一对象的“sizeof”的不同答案
- javascript - 如果满足条件则匹配整个单词