This is more a SQL question/answer than Go specific so the possible solutions are SQL based.
Possible solutions:
(1) REPLACE INTO
REPLACE INTO books
(id, title, author, year_published)
VALUES
(1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
This would overwrite an existing record. Works on unique constraint(s). Though when a matching record is found it will be deleted and thus it might a not wanted behavior.
(2) INSERT IGNORE
INSERT IGNORE INTO books
(id, title, author, year_published)
VALUES
(1, 'Green Eggs and Ham', 'Dr. Seuss', 1960);
This would add if the record does not exist. Works on unique constraint(s).
From the handbook:
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) INSERT ... ON DUPLICATE KEY UPDATE
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';
If the insert fails the values from ON DUPLICATE KEY
will be used to make an update statement.
To do a backup create a history table ( a table with the same structure but amended with columns to get the change date ) and do a INSERT ... SELECT
. To be atomic you would probable need to use transactions with the correct locking strategy - not sure how to get this right for MySQL.
Reference: