Mysql暂时压制唯一索引

Nam*_*ess 13 mysql sql indexing sql-update

我有一个在两列上有唯一索引的表,id_parent和sort_order是准确的

+----+-----------+------------+-------------+-------------+-------------+
| id | id_parent | sort_order | some_data   | other_data  | more_data   |
+----+-----------+------------+-------------+-------------+-------------+
| 1  |         1 |          1 | lorem ipsum | lorem ipsum | lorem ipsum |
| 2  |         1 |          2 | lorem ipsum | lorem ipsum | lorem ipsum |
| 3  |         1 |          3 | lorem ipsum | lorem ipsum | lorem ipsum |
+----+-----------+------------+-------------+-------------+-------------+
Run Code Online (Sandbox Code Playgroud)

现在我想一次性更新它们,它们的数据和sort_order.1 - 2 - 3例如,sort_order将从更改为2 - 3 - 1.

但是,当我开始运行更新语句时,唯一索引阻止我,就像预期的那样,说我不能有两行id_parent = 1 and sort_order = 2.好吧,我现在可以设置它4,按正确的顺序更新其他行,然后设置这个.但是,我必须运行一个额外的声明,并且很可能为我的脚本语言添加额外的逻辑以确定更新的正确顺序.我也使用ORM,它变得更加不方便.

我现在的问题是,是否有一些方法可以让mysql暂时忽略这个索引?就像启动特殊事务一样,只有在提交索引之前才会计算索引?

And*_*and 6

据我所知,这是不可能的.

我唯一一次看到这样的东西就是你可以在myisam表上禁用非唯一键.但不是在InnoDB而不是在唯一键上.

但是,为了节省一两个更新,不需要确切的数字1,2和3.你可以有4,5和6.对吗?您将按顺序使用它,而不是其他任何内容,因此确切的数字并不重要.如果你聪明的话它甚至可以为你节省更新.从你的例子

update table set sort_order = 4 where sort_order = 1 and id = 1 and id_parent = 1;
Run Code Online (Sandbox Code Playgroud)

新的排序顺序是2,3,1.只需一次更新.


And*_*y M 5

“但是,当我开始运行更新语句时 ……” –我了解,您尝试使用多个UPDATE语句来更新值,例如在循环中。是这样吗?一口气更新它们怎么样?像这样:

UPDATE atable
SET sort_order = CASE sort_order WHEN 3 THEN 1 ELSE sort_order + 1 END
WHERE id_parent = 1
  AND sort_order BETWEEN 1 AND 3
Run Code Online (Sandbox Code Playgroud)

单个语句是原子的,因此,在此更新结束时,的值(sort_order尽管已更改)仍保持唯一。

抱歉,我无法在MySQL中进行测试,但是它绝对可以在SQL Server中运行,并且我相信这种行为符合标准。

  • 除非以正确的顺序实际更新了行,否则这行不通。在执行过程中,绝对不能违反唯一密钥。如果没有降序排序,`update sorttest set sort = sort + 1 order by sort desc;`将不起作用,即使第二行将要移出位置,第一行也会违反键。 (3认同)

Sim*_*ast 5

注意:一些评论提到下面的答案并不总是抑制唯一约束,尤其是在 InnoDB 中。如果您可以改进此答案,请单击“编辑”并进行改进。

您可以简单地在脚本的开头添加这一行:

SET UNIQUE_CHECKS=0;
Run Code Online (Sandbox Code Playgroud)

将此与以下各项结合使用是很常见的:

SET FOREIGN_KEY_CHECKS=0;
Run Code Online (Sandbox Code Playgroud)

UNIQUE_CHECKS此处的文档中提到了该变量:http :
//dev.mysql.com/doc/refman/5.0/en/converting-tables-to-innodb.html

  • 刚刚在 5.6 上试过这个,不适用于 InnoDB。重复键仍然引发错误。 (3认同)
  • 引自 Mysql 文档:`unique_checks 允许但不需要存储引擎忽略重复键。` Innodb 似乎不支持此功能。 (2认同)