惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
V
Vulnerabilities – Threatpost
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
S
Secure Thoughts
Microsoft Azure Blog
Microsoft Azure Blog
Blog — PlanetScale
Blog — PlanetScale
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
云风的 BLOG
云风的 BLOG
The Last Watchdog
The Last Watchdog
L
LINUX DO - 热门话题
酷 壳 – CoolShell
酷 壳 – CoolShell
WordPress大学
WordPress大学
AWS News Blog
AWS News Blog
美团技术团队
G
Google Developers Blog
宝玉的分享
宝玉的分享
www.infosecurity-magazine.com
www.infosecurity-magazine.com
C
CXSECURITY Database RSS Feed - CXSecurity.com
Recent Commits to openclaw:main
Recent Commits to openclaw:main
I
InfoQ
小众软件
小众软件
Google DeepMind News
Google DeepMind News
P
Privacy & Cybersecurity Law Blog
Stack Overflow Blog
Stack Overflow Blog
Webroot Blog
Webroot Blog
D
DataBreaches.Net
IT之家
IT之家
PCI Perspectives
PCI Perspectives
人人都是产品经理
人人都是产品经理
Hacker News: Ask HN
Hacker News: Ask HN
L
LangChain Blog
SecWiki News
SecWiki News
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Cisco Blogs
T
Threatpost
P
Proofpoint News Feed
Y
Y Combinator Blog
Cloudbric
Cloudbric
T
Tor Project blog
量子位
博客园_首页
B
Blog
Hugging Face - Blog
Hugging Face - Blog
GbyAI
GbyAI
D
Darknet – Hacking Tools, Hacker News & Cyber Security

博客园 - ayanmw

极度推荐: 9router 一个npm服务,可以让你将白嫖到的所有AI token以及付费API都集中到一起 开源项目介绍 OpenTeam 命令行 检测验证网站的 SSL证书 是否安全 Nginx 使用自签名 SSL 证书 关闭夸克浏览器在windows资源管理器中,图片右键菜单的万能转换开关 golang的defer 深坑 Windows Terminal 清屏方法 Ctrl+Shift+K 免费二级域名以及设置SSL证书和解析 docker加速镜像 golang + AI 写一个可以 一键让nas下载百度网盘链接的文件 的程序 raid 为什么而不可以两个硬盘交叉读写和交叉备份? google-protobuf库 在golang语言下的插件扩展 golang 空切片和nil切片 有区别吗? golang json库 忽略 omitempty Go语言: golang如何判断一个结构体的一个方法是匿名组合的,还是该结构体自己的方法? golang 获得一个结构体的字节大小 吐槽 WPS 流氓行为: WPS 未经用户允许, 就建立了 WPS本地云盘 , 然后 云文档的文件 莫名其妙的的被删除了, 现在只能开会员恢复WPS云空间回收站的文件. 预测未来会有 内嵌AI大模型的游戏 好奇: windows10+都可以运行多个linux子系统了,为什么不支持运行多个windows子系统呢? gorm使用事务并发情况下切有最大mysql连接数限制的情况下的BUG,踩坑了 2024年 个人养老金 账户 应知应会
两个Mysql唯一索引的交换: 避免重复索引 Duplicate entry '3' for key 'priority_UNIQUE'
ayanmw · 2024-01-10 · via 博客园 - ayanmw

需求

我做了一个排行榜,但是主键是pid,不是排名,排名作为唯一索引,两个人排名交换,只需要交换 排名唯一索引值即可.
但是直接单独更新 提示错误: Duplicate entry '3' for key 'priority_UNIQUE'

方法

本来希望可以在一条SQL语句中交换两个唯一索引值,但是发现这是不可能的,因为值得修改是一个一个 修改的,但凡修改为了 其他唯一索引值 就会报错.
所以只能先把两个记录的值 修改为 负数(保证仍然不会重复的值) , 然后再修改为需要交换的值,这样就可以达成需求,不过这个过程需要4条SQL语句.

后来发现 一条SQL语句修改两个值的, 那么就可以缩减为 2条SQL语句,为了避免错误导致只修改了一般,所以一般使用SQL事务.

SQL事务代码如下:

START TRANSACTION ;

UPDATE tasks
SET priority =
CASE
WHEN priority = 2 THEN -3
WHEN priority = 3 THEN -2
END
WHERE priority IN (2,3) ;

UPDATE tasks
SET priority = - priority
WHERE priority IN (-2,-3) ;

COMMIT ;

参考资料

mysql 互换两行,如何在不违反唯一约束的情况下在MySQL中交换两行的值?

I have a "tasks" table with a priority column, which has a unique constraint.

I'm trying to swap the priority value of two rows, but I keep violating the constraint. I saw this statement somewhere in a similar situation, but it wasn't with MySQL.

UPDATE tasks

SET priority =

CASE

WHEN priority=2 THEN 3

WHEN priority=3 THEN 2

END

WHERE priority IN (2,3);

This will lead to the error:

Error Code: 1062. Duplicate entry '3' for key 'priority_UNIQUE'

Is it possible to accomplish this in MySQL without using bogus values and multiple queries?

EDIT:

Here's the table structure:

CREATE TABLE `tasks` (

`id` int(11) NOT NULL,

`name` varchar(200) DEFAULT NULL,

`priority` varchar(45) DEFAULT NULL,

PRIMARY KEY (`id`),

UNIQUE KEY `priority_UNIQUE` (`priority`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8

解决方案

Is it possible to accomplish this in MySQL without using bogus values and multiple queries?

No. (none that I can think of).

The problem is how MySQL processes updates. MySQL (in difference with other DBMS that implement UPDATE properly), processes updates in a broken manner. It enforces checking of UNIQUE (and other) constraints after every single row update and not - as it should be doing - after the whole UPDATE statement completes. That's why you don't have this issue with (most) other DBMS.

For some updates (like increasing all or some ids, id=id+1), this can be solved by using - another non-standard feature - an ORDER BY in the update.

For swapping the values from two rows, that trick can't help. You'll have to use NULL or a bogus value (that doesn't exist but is allowed in your column) and 2 or 3 statements.

You could also temporarily remove the unique constraint but I don't think that's a good idea really.

So, if the unique column is a signed integer and there are no negative values, you can use 2 statements wrapped up in a transaction:

START TRANSACTION ;

UPDATE tasks

SET priority =

CASE

WHEN priority = 2 THEN -3

WHEN priority = 3 THEN -2

END

WHERE priority IN (2,3) ;

UPDATE tasks

SET priority = - priority

WHERE priority IN (-2,-3) ;

COMMIT ;