On Duplicate Update不适用于唯一索引

Sla*_*ice 1 mysql database-indexes

我试图插入/更新我的SQL表有这个定义:

CREATE TABLE `place`.`a_table` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`some_id` bigint(20) NOT NULL,
`someOther_id` bigint(20) NOT NULL,
`some_value` text,
`re_id` bigint(20) NOT NULL DEFAULT '0',
`up_id` bigint(20) NOT NULL DEFAULT '0',
PRIMARY KEY (`id`),
KEY `some_id_key` (`some_id`),
KEY `some_id_index1` (`some_id`,`someOther_id`),
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4;
Run Code Online (Sandbox Code Playgroud)

如您所见,some_id和someOther_id共享一个索引.

我正在尝试执行我的插入/更新语句,如下所示:

INSERT INTO `a_table` (`re_id`,`some_id`,`someOther_id`,`up_id`,`some_value`) VALUES      
(100,181,7,101,'stuff in the memo wow') On DUPLICATE KEY UPDATE 
`up_id`=101,`some_value`='sampleValues'
Run Code Online (Sandbox Code Playgroud)

我希望因为我没有指定id,所以它将作为插入/更新规则返回到索引键(some_id_index1).但是,它只是插入.

显然这是不正确的.我在这做错了什么?

Ste*_*lly 6

好的,首先是帮你提出更好的问题.你的问题的字面答案"我在这里做错了什么?" 没什么.

您有一个包含自动增量主键和两个非唯一二级索引的表.您正在向该表插入行而不指定主键的值,因此MySQL将使用自动增量规则为其提供唯一键,因此该ON DUPLICATE KEY条件永远不会触发.事实上,人们可能会认为这是多余的.

所以你必须问自己的问题是你认为应该发生什么.现在Stack Overflow不是一个论坛,所以不要回来为这个问题添加评论,试图澄清你的原始问题.而是制定一个新问题,使那些试图准确回答你所问的内容的人清楚.

在我看来,有很多可能性:

  1. 您希望将辅助索引修改为唯一.一旦你这样做,它将触发ON DUPLICATE KEY规则并切换到更新
  2. 实际上,您根本不需要自动增量列,some_id实际上应该是您的主键
  3. 您不了解数据库索引的工作原理(具体而言,至少有一个二级索引可能是不必要的,因为数据库通常可以组合多个索引或使用部分索引来优化您的查询,因此第二个二级索引更有用只有someOther_id字段的索引,除非你有强制执行的特定唯一性约束.例如,如果你期望多行具有相同some_id但只有一行特定someOther_id的任何特定行,some_id那么将需要第二个二级索引,但是那个案例第一个不会因为数据库可以使用第二个作为部分索引来实现相同的性能优化)

我建议你用一支笔和一张纸坐下来远离你的电脑,并试着写下你想做的确切方式,以便选择一个:你的毕业生; 一个十一岁的孩子]可以理解.把那张纸收起来扔掉,直到你可以一口气写下来,不会犯任何错误.然后返回计算机并尝试编写刚刚编写的内容.

100次中99次你会发现这有助于你解决问题,而不需要问别人问题,因为我们的问题中有99次是因为我们自己对问题本身缺乏了解.试图(虚拟地)向你的祖母或十一岁的孩子解释你的问题,迫使你抛弃一些让你眼花缭乱的假设,并在你睁开眼睛看到他们停止付款之前看到问题的核心注意.[我不是说你实际上和你的祖母/一个十一岁的孩子一起编程]

这是我想象中的一个问题陈述的一个例子.这可能是不正确的,因为我不知道你的具体问题是什么:

We need a table that provides cross-reference notes about two other tables. 
There are different types of cross-reference (we use the column 're_id' to 
identify the type of cross-reference) and there are different types of notes 
(we use the columns 'up_id' as well as 'someValue') to store the actual notes.
The cross-reference is indicated with two columns 'some_id' which is the id
of the row in the 'some' table and 'someOther_id' which is the id of the row
in the 'someOther' table. There can be only one cross-reference between any one
row in the 'some' table and any one row in the 'someOther' table, but there can
be multiple cross-references from one specific row in the 'some' table to different
rows in the 'someOther' table.
Run Code Online (Sandbox Code Playgroud)

使用上面的问题陈述,我会将主键从自动增量切换为两列主键,(some_id,someOther_id)并删除所有辅助键!

但我希望您意识到您的实际解决方案实际上可能不同,因为您的问题陈述与我的猜测不同.