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暂时忽略这个索引?就像启动特殊事务一样,只有在提交索引之前才会计算索引?
据我所知,这是不可能的.
我唯一一次看到这样的东西就是你可以在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.只需一次更新.
“但是,当我开始运行更新语句时 ……” –我了解,您尝试使用多个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中运行,并且我相信这种行为符合标准。
注意:一些评论提到下面的答案并不总是抑制唯一约束,尤其是在 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
| 归档时间: |
|
| 查看次数: |
10860 次 |
| 最近记录: |