原子更新和备份ON DUPLICATE KEY插入else-Golang SQL语句

时间:2018-11-20 10:02:00

标签: mysql sql go

结合两个语句(INSERT或(BACKUP和UPDATE))并在golang中自动执行它们的最佳方法是什么?

我发现了类似的问题: https://codereview.stackexchange.com/questions/186909/query-select-and-insert-if-not-exists?newreg=067063956a834327883542c3171a22d4

但是解决方案不满足以下两个要求:

  1. 执行值ON DUPLICATE KEY的备份,
  2. 使用标准SQL
  3. 不使用存储过程,但
  4. 保持原子性。

1 个答案:

答案 0 :(得分:0)

与Go特定的问题相比,这更多的是SQL问题/答案,因此可能的解决方案基于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);

如果记录不存在,则会添加。适用于唯一约束。

从手册:

  

如果使用IGNORE修饰符,则在执行   INSERT语句被忽略。例如,如果没有IGNORE,则该行   复制表中现有的UNIQUE索引或PRIMARY KEY值   导致重复键错误,并且语句中止。用   忽略,该行将被丢弃,并且不会发生错误。忽略的错误可能   生成警告,尽管不会出现重复键错误。

(3)插入...在重复密钥更新上

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。

参考: