追溯更改 MySQL 数据库

发布于 2025-01-07 14:39:54 字数 178 浏览 0 评论 0原文

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

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

有没有一种方法可以只应用结构更改而不用一个数据库完全替换另一个数据库?

Is there a method to track changes to a MySQL database? I develop offline and then commit all the changes to my server. For the app itself I use Git and it works nicely.

However, for the database, I'm changing everything manually because the live database contains customer data and I cannot just replace it with the development database.

Is there a way to only have the structural changes applied without completely replacing one db with another?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

独行侠 2025-01-14 14:39:54

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

对于 PHP,您可以查看 Doctrine

对于 Ruby,它是 Rails

The term you're looking for is 'database migrations' (and no, it doesn't refer to moving from one RDBMS to another). Migrations are a way to programatically version control your database structure. Most languages have some kind of migrations toolkit, often as part of an ORM library/framework.

For PHP you can look at Doctrine

For Ruby it's Rails of course

甜尕妞 2025-01-14 14:39:54

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

现在,这是一个广阔的领域。您要做的第一件事是决定是否要跟踪数据库中的某种数据。如果是这种情况,您有多种选择,使用 LVM复制InnoDB二进制日志,简单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);

现在我们要将数据复制到新表。我们需要先解决一些其他问题,我会逐一解释。

首先,您可以在更改表时允许其他连接修改客户表,因此我将发出锁。如果您想了解更多信息,请访问此处

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 表重命名为其他名称或将其移动到其他数据库。

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

就是这样,希望有帮助。

The key to have keep track of your changes is Snapshots my friend.

Now, it's a wide field. The first thing you have to do is decide if you want to keep track of your database with some kind of data in it. If that's the case you have several options, from using LVM, copying InnoDB binary logs, and the simple mysqldump.

Now, if what you wanna do is have some smooth transition between your database changes (i mean, you added a column, for example), you have some other options.

The first one is replication. That's a great option, but is a little complex. With replication you may alter one slave and after it's done, with some locking, you can make it master, and replace master, and so on. It's really difficult, but is the better option.

If you cannot afford replication, what you must do is apply the changes to your single-master DB with the minimum downtime. Some good option is this:

Suppose you want to replace your Customer table to add a "facebook_account" field. First, you can use an alias table, like this:

The original table (it has data):

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

The new one:

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;

Or simply:

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

Now we're gonna copy the data to the new table. We'll need to issue some other things first, i'll explain them each at a time.

First, you can allow other connections to modify the customer table while your making the change of table, so i'll issue a lock. If you want to learn more about this go here:

LOCK TABLES customer WRITE ,new_customer WRITE;

Now i flush the table to write any cache content to the filesystem:

FLUSH TABLES customer;

Now we can do the insert. First I disable the keys for performance issues. After the data is inserted i enable the keys again.

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;

Now we can switch the tables.

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

Finally we have to release the lock.

UNLOCK TABLES;

That's it. If you want to keep track of your modified tables you may want to rename your old_customer table, to something else or move it to other database.

The only issue i didn't cover here is about Triggers. You have to pay atention to any enabled trigger, but it will depend on your schema.

That's it, hope it helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文