我有一个存储用户发布文章的数据库。所有者可以随时修改他们的文章。
我确实想要添加备用功能,以防用户意外删除文章内容或更新时出现其他错误。
出于这个原因,我有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
。
我已经看到了关于如何获得副本的一些答案,但这些答案似乎严格适用于update
和insert
,并且似乎不适用于{{1查询。我更喜欢一个超过两个的陈述,这就是我遇到麻烦的地方。
有没有办法在一个Replace语句中实现这样的副本?
答案 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
语句。相反,总是使用第二个;