在 golang 中组合两个语句(INSERT 或(BACKUP 和 UPDATE))并自动执行它们的最佳方式是什么?
但是解决方案没有满足以下要求中的 2 个:
- 对 DUPLICATE KEY 的值进行备份,
- 使用标准 SQL
- 不使用存储过程但是
- 保持原子性。
最佳答案
这更像是一个 SQL 问题/答案,而不是特定于 Go 的,因此可能的解决方案是基于 SQL 的。
可能的解决方案:
(1) 替换成
REPLACE INTO books
(id, title, author, year_published)
VALUES
(1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
这将覆盖现有记录。适用于唯一约束。虽然当找到匹配记录时,它将被删除,因此这可能是不希望的行为。
(2) 插入忽略
INSERT IGNORE INTO books
(id, title, author, year_published)
VALUES
(1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
如果记录不存在,这将添加。适用于唯一约束。
来自手册:
If you use the IGNORE modifier, errors that occur while executing the INSERT statement are ignored. For example, without IGNORE, a row that duplicates an existing UNIQUE index or PRIMARY KEY value in the table causes a duplicate-key error and the statement is aborted. With IGNORE, the row is discarded and no error occurs. Ignored errors may generate warnings instead, although duplicate-key errors do not.
(3) 插入 ... 在重复 key 更新时
INSERT INTO books
(id, title, author, year_published)
VALUES
(1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
ON DUPLICATE KEY UPDATE
title = 'No Green Eggs and Ham';
如果插入失败,ON DUPLICATE KEY
中的值将用于生成更新语句。
要进行备份,请创建历史表(具有相同结构但用列进行修改以获得更改日期的表)并执行 INSERT ... SELECT
。要成为原子的,您可能需要使用具有正确锁定策略的事务 - 不确定如何为 MySQL 做到这一点。
引用:
关于mysql - 原子更新和备份 ON DUPLICATE KEY insert else - golang sql 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53390487/