我想创建一个测试数据库,每天使用生产数据库中的数据进行刷新。
但,我希望能够在测试数据库中创建记录并保留它们而不是覆盖它们。
我想知道是否有一种简单直接的方法来做到这一点。
两个数据库都在同一台服务器上运行,因此显然排除了复制?
为了澄清起见,以下是我希望发生的事情:
- 使用生产数据创建测试数据库
- 我创建了一些想要在测试服务器上继续运行的测试记录(基本上这样我就可以拥有可以使用的示例记录)
- 第二天,数据库被完全刷新,但我当天创建的记录被保留。当天未更改的记录将被生产数据库中的记录替换。
复杂的是,如果生产数据库中的一条记录被删除,我希望它也在测试数据库中被删除,所以我确实想删除测试数据库中不再存在于生产数据库中的记录,除非这些记录是在测试数据库中创建的。
似乎唯一的办法就是用某种表来存储正在创建的记录的元数据?例如,像这样:
CREATE TABLE MetaDataRecords (
id integer not null primary key auto_increment,
tablename varchar(100),
action char(1),
pk varchar(100)
);
DELETE FROM testdb.users
WHERE
NOT EXISTS (SELECT * from proddb.users WHERE proddb.users.id=testdb.users.id) AND
NOT EXISTS (SELECT * from testdb.MetaDataRecords
WHERE
testdb.MetaDataRecords.pk=testdb.users.pk AND
testdb.MetaDataRecords.action='C' AND
testdb.MetaDataRecords.tablename='users'
);
答案1
我想你可能会发现合并表在这里很有用。只需将测试数据保存在一个表中;并在另一个表中保存来自生产的每日快照;并将这两个表合并。
答案2
我来过这里,并且愿意稍微修改我的工作流程,以尽量减少我的测试数据库中应该被替换的生产数据的风险。
我所做的只是:
mysqldump
生产- 将 SQL 注入到转储的末尾,
assert
它就在文件中(文件写入时永远不能太小心) - 将此备份恢复到测试数据库中。
您注入的 SQL 应该单独维护,可能在另一个脚本中。这些通常称为测试夹具。从您的 DB 实现中抽象出来,减少对“魔法”的依赖(即,在您的情况下,diff
将您的测试数据库与其之前的还原进行对比,以查看已添加的内容,然后查看从实时数据库中删除的内容,交叉引用主键/外键等),这样出错的可能性就会小得多,最终您会向真正的用户发送电子邮件,而不是向测试用户发送电子邮件。
(对我来说)一个优点是做类似的事情:
UPDATE users SET email = CONCAT('gmailusername+', users.name, '@gmail.com')`;
这是一个超级故障保护措施,以防所有其他途径都失败(例如您的模拟 SMTP 服务器),并且邮件会漏掉(再次强调,对于这些事情,再怎么小心也不为过)。