如何使用其他数据库中的数据更新MySQL数据库?

时间:2017-06-01 07:54:59

标签: mysql ruby-on-rails database

免责声明:这是一个"最佳做法"问题,但我不确定如何用它来表达更具体或更客观的答案。

我有一个小型Rails项目的两个数据库:一个dev数据库和一个prod数据库,它们位于同一台服务器上。

每隔几周,我会通过一个dev Rails环境,通过ActiveAdmin gem对dev数据库进行一些数据更改(主要是插入)。我在Rails应用程序上查看,确保新数据看起来不错。当我准备好部署时,我运行一个脚本:

  1. 转储dev db
  2. 删除并重新创建prod db以删除所有数据
  3. dev db转储导入prod db
  4. 我的直觉告诉我,这不是解决这个问题的好方法,而且它也有点慢,但我似乎无法找到从一个数据库进行数据部署的标准方法到另一个。什么是标准方式,如果有的话?

    我考虑过的事情:

    • 设置另一个数据库,该数据库是dev数据库的副本;在部署中,以某种方式切换Rails应用程序以使用副本作为" prod",更新旧的" prod" db是复制品等等。我几乎无法将这个想法保留在我的脑海中,而且看起来像是一团糟。
    • 直接在prod上进行数据更改,这完全使开发人员数据库的需求无效(感觉非常粗糙)
    • 通过带有事务的SQL脚本在dev中进行数据更改,并在部署时将它们应用于prod(实际上,非常讨厌手工编写这些脚本)

    一些补充说明:

    • 我所做的唯一数据更改是
    • 架构更改通过Rails迁移完成
    • 数据库相对较小(最大的表是~1000行)

2 个答案:

答案 0 :(得分:2)

如果同一服务器上有两个数据库,则可以比较并插入表中。首先,对于已删除的行:

BEGIN TRAN;
DELETE FROM prod.tbl1
WHERE id IN (
 SELECT id FROM dev.tbl1 RIGHT JOIN prod.tbl1 ON dev.tbl1.id = prod.tbl1.id WHERE dev.tbl1.id IS NULL);
COMMIT;

其次,对于新行:

BEGIN TRAN;
INSERT INTO prod.tbl1
SELECT *
FROM dev.tbl1
WHERE id IN (
 SELECT id FROM dev.tbl1 LEFT JOIN prod.tbl1 ON dev.tbl1.id = prod.tbl1.id WHERE prod.tbl1.id IS NULL);
COMMIT;

现在,您的dev数据库上的触发器用于管理更新:

CREATE DEFINER=`root`@`localhost` TRIGGER `dev`.`tbl1_update`
AFTER UPDATE ON `dev`.`tbl1`
FOR EACH ROW
BEGIN
    SET NEW.update = '1';
END

您需要更新"开发表上的字段。当在表上运行更新查询时,字段"更新"自动更改为1。然后,使用此查询:

BEGIN TRAN;
UPDATE prod.tbl1
LEFT JOIN dev.tbl1
    ON prod.tbl1.id = dev.tbl1.id
SET prod.tbl1.fld1 = dev.tbl1.fld1, prod.tbl1.fld2 = dev.tbl1.fld2
WHERE prod.tbl1.id IN (SELECT id FROM dev.tbl1 WHERE update = '1');
UPDATE dev.tbl1 SET update = '0';
COMMIT;

您可以在所有表​​格上运行这样的查询。您可以将它放在.sql文件中并使用cron作业运行(mysql -h -u -D< myscript.sql)。

此查询比较表并获取生产中不存在的dev上的ID。然后,对整个表执行select(仅这些id),并将它们插入prod。

(用每个表的唯一标识符替换id字段)。

答案 1 :(得分:2)

这似乎是一种非常奇怪的方法。通常development中的数据被视为一次性数据。您只需要足够的数据,以便进行样式设置和故障排除 - 通常使用伪随机数据。建立"完成"开发中的应用程序数据似乎容易出错,如果您是多个开发人员,则需要同步工作。

另外,如果数据集非常大,由于缺少缓存,Rails的开发速度会很慢。

您想要的是一个临时环境,它在与预期生产相同的设置下运行。这里的关键是它应该尽可能接近生产。这可以在远程服务器或Intranet中的服务器上运行。

您还可以使用暂存环境向客户/利益相关者显示新功能或进度,让他们预览新功能或循环开发进度。

您可以通过复制config/environments/production.rb -> staging.rb并在预期的登台服务器上将RAILS_ENV env var设置为staging来创建它。

您还应该在config/database.yml中创建其他部分或使用ENV['DATABASE_URL']

根据项目,可以使用生产中的镜像数据每天刷新暂存,也可以完全同步。