回顾性地更改MySQL数据库

时间:2012-02-21 11:36:53

标签: mysql version-control

是否有跟踪MySQL数据库更改的方法?我离线开发然后将所有更改提交到我的服务器。对于应用程序本身,我使用Git,它运行良好。

但是,对于数据库,我手动更改所有内容,因为实时数据库包含客户数据,我不能只用开发数据库替换它。

有没有办法只应用结构更改而不用一个db完全替换另一个?

2 个答案:

答案 0 :(得分:0)

您正在寻找的术语是“数据库迁移”(不,它并不是指从一个RDBMS转移到另一个RDBMS)。迁移是一种以编程方式控制数据库结构的方法。大多数语言都有某种迁移工具包,通常作为ORM库/框架的一部分。

对于PHP,您可以查看Doctrine

对于Ruby来说,当然是Rails

答案 1 :(得分:0)

跟踪您的更改的关键是Snapshots我的朋友。

现在,这是一个广阔的领域。您要做的第一件事是决定是否要使用其中的某种数据跟踪数据库。如果是这种情况,您可以选择使用LVMcopying InnoDB binary logs和简单mysqldump

现在,如果您想要做的是在数据库更改之间进行一些平滑过渡(例如,您添加了一个列),那么您还有其他选择。

第一个是复制。这是一个很好的选择,但有点复杂。通过复制,您可以更改一个从站,完成后,通过一些锁定,您可以使其成为主站,并替换主站,依此类推。这真的很难,但是更好的选择。

如果您无法负担复制费用,您必须执行的操作是将更改应用于您的单主数据库,并将停机时间降至最低。一个很好的选择是:

假设您要替换Customer表以添加“facebook_account”字段。首先,您可以使用别名表,如下所示:

原始表(它有数据):

CREATE TABLE `customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

新的:

CREATE TABLE `new_customer` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `facebook_account` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB;

或者简单地说:

CREATE TABLE new_customer LIKE customer;
ALTER TABLE new_customer add column facebook_account VARCHAR(255);

现在我们要将数据复制到新表中。我们首先需要发布一些其他的东西,我会一次解释一下。

首先,您可以允许其他连接在您更改表时修改customer表,因此我将发出锁定。如果您想了解更多相关信息,请转到here

LOCK TABLES customer WRITE ,new_customer WRITE;

现在我刷新表以将任何缓存内容写入文件系统:

FLUSH TABLES customer;

现在我们可以进行插入了。首先,我禁用了性能问题的密钥。插入数据后,我再次启用密钥。

ALTER TABLE new_customer DISABLE KEYS;
INSERT INTO new_customer(id,name,facebook_account) SELECT customer.id,customer.name, Null FROM customer;
ALTER TABLE new_customer ENABLE KEYS;

现在我们可以切换表了。

ALTER TABLE customer RENAME old_customer;
ALTER TABLE new_customer RENAME customer;

最后我们必须释放锁。

UNLOCK TABLES;

就是这样。如果要跟踪修改后的表,可能需要将old_customer表重命名为其他内容或将其移动到其他数据库。

我在这里没有涉及的唯一问题是关于触发器。您必须注意任何已启用的触发器,但这取决于您的架构。

就是这样,希望它有所帮助。