在Replace Into之前将字段复制到列中

时间:2015-12-06 16:36:01

标签: mysql sql

我有一个存储用户发布文章的数据库。所有者可以随时修改他们的文章。

我确实想要添加备用功能,以防用户意外删除文章内容或更新时出现其他错误。

出于这个原因,我有content列存储文章的内容,以及backup_content,用于在上次更新之前保留内容的副本。

用户有一个“恢复”按钮,用于用备份替换新内容。非常像“撤消”功能。

我准备好的插入/更新文章的声明如下:

REPLACE INTO custom_pages (name, banner_url, full_url, backup_content, content, updated_on) VALUES (?, ?, ?, content, ?, CURRENT_TIMESTAMP);

在这里,我尝试将content的先前值放在backup_content中,然后使用新值更改content。这样做会将backup_content设置为NULL

我已经看到了关于如何获得副本的一些答案,但这些答案似乎严格适用于updateinsert,并且似乎不适用于{{1查询。我更喜欢一个超过两个的陈述,这就是我遇到麻烦的地方。

有没有办法在一个Replace语句中实现这样的副本?

Table Image

2 个答案:

答案 0 :(得分:1)

评论太长了。

我认为您应该重新考虑一下您的数据结构。如果要保留历史记录,请使用单独的表而不是列。像custom_pages_history这样的东西。您可以从表中删除backup_content列,而是依赖历史记录表。

然后,在插入和更新插入行的历史记录表中定义触发器。

这种方法的优点是:

  • 您有所有文章的完整历史记录。
  • 更改将加盖时间戳。
  • 如果需要,用户可以返回到文章的任何早期版本。

这并不能直接回答您关于替换的问题。您可以从历史记录表中进行更新,而不是replace

答案 1 :(得分:1)

我还支持Gordon Linoff's suggestion支持您通过触发器和一对多相关表创建连续更新历史记录。

但是,如果您现在无法进行重大的体系结构更改,则可以实现正在尝试的内容with INSERT INTO...ON DUPLICATE KEY UPDATE,而不是旧的REPLACE INTO功能。

使用REPLACE INTO...SELECT FROM可能会导致对表索引进行多次访问,但INSERT INTO...ON DUPLICATE KEY UPDATE只能访问一次。

由于name具有唯一索引,因此假设您永远不会尝试UPDATE,而是始终执行INSERT,将旧值复制到backup_content

-- Inserting a row which does not yet exist..
INSERT INTO custom_pages (name, banner_url, full_url, content)
  VALUES ('uniquename', 'http://example.com', 'http://example.com', 'this is the original content');



-- In practice, you use this format:
-- uniquename already exists, so update necessary fields
INSERT INTO custom_pages (name, banner_url, full_url, content) 
  VALUES ('uniquename', 'http://example.com', 'http://example.com', 'this is new content')
  ON DUPLICATE KEY UPDATE
    -- Update from the VALUES() list
    banner_url = VALUES(banner_url),
    -- Set backup_content to old content BEFORE updating
    -- content from VALUES()
    backup_content = content,
    content = VALUES(content),
    updated_on = NOW();

使用此方法,如果没有INSERT子句,则永远不会使用第一个ON DUPLICATE KEY语句。相反,总是使用第二个;

将创建唯一键不存在的行,已存在的行。

这里有效:http://sqlfiddle.com/#!9/2f687/1