首页 > 解决方案 > 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_idandsuffix_id不为空,但因为它们引用公共前缀和后缀,所以它们不是唯一的。其余的行只是非空值。

理想情况下,我想检查一个新用户是否与另一个用户完全相同prefix_idsuffix_id并增加identifier_index.

我用多个(SELECT 然后 INSERT)语句尝试了这个,但我担心数据可能不会更新/唯一(另一个用户可能在您插入的时间之间插入,等等)。

这可能在单个插入语句中吗?我读过,ON DUPLICATE KEY但我不确定这是否适用于此。

更新:

根据下面的评论和答案,我为有问题的三列创建了一个唯一索引: 在此处输入图像描述

但是,identifier_index即使 prefix_id 和 suffix_id 不同,也会增加。在最后一个条目的情况下,根本不会增加导致重复条目错误:

在此处输入图像描述

标签: mysql

解决方案


这是个好问题。我不是开发人员,但从数据库管理员的角度来看,我会说你需要这样做。

您肯定需要一个跨越 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';

但请注意,您可能会遇到死锁问题。当另一个事务在此查询仍在运行时尝试插入时,就会发生这种情况。不过,死锁并不是什么严重的问题。通常,应用程序以某种方式构建,它只是再次尝试,直到插入成功。


推荐阅读