如何为 PHP/MySQL 应用程序自动迁移(模式和数据)

Posted

技术标签:

【中文标题】如何为 PHP/MySQL 应用程序自动迁移(模式和数据)【英文标题】:How to automate migration (schema and data) for PHP/MySQL application 【发布时间】:2009-05-05 16:35:16 【问题描述】:

我有一个 php/mysql 应用程序。我正在寻找一种自动方式升级应用程序背后的数据库。 升级后我不需要兼容旧版本。

我已阅读 jeff's 和 K. Scott Allen's 关于此的文章。

我仍然不确定如何为 PHP/MySQL 应用程序实现这一点。

有没有什么简单又好的流程呢?

【问题讨论】:

【参考方案1】:

我有一个我使用的“架构”对象 - 但你可以在没有类的情况下做同样的事情..

您要做的是创建一个“db_schema_versions”表:

CREATE TABLE db_schema_versions (
  `table` varchar(255) NOT NULL PRIMARY KEY, 
  `version` INT NOT NULL
)

在您的数据库可以跟踪它所在的版本之后 - 它可以自动进行 SQL 升级。

您应该在升级架构时锁定您的架构表。这样您就不会同时有两个请求尝试升级您的架构。

所以 - 跟踪您要升级的版本 - 构建一个大交换机 - 像这样:

class SNTrack_Db_Schema extends MW_Db_Schema_Abstract 
  protected $table = "sntrack_db_schema";
  protected $version = 5;

  protected function upgrade($fromVersion) 
    // don't break
    switch($fromVersion) 
      case 0:
        $this->db->query('CREATE TABLE sntrack_inbound_shipment (
            `id` INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
            `from` VARCHAR(255) NOT NULL,
            `date` DATE NOT NULL,
            `invoice` VARCHAR(255) NOT NULL,
            `notes` TEXT
          )');
        $this->setVersion(1);
      case 1:
        $this->db->query('ALTER TABLE sntrack_details ADD `shipment_id` INT');
        $this->db->query('ALTER TABLE sntrack_product ADD `inventory` INT NOT NULL DEFAULT 0');
        $this->db->query('CREATE TABLE sntrack_inventory_shipment (
            `shipment_id` INT NOT NULL,
            `product_id` INT NOT NULL,
            `qty` INT NOT NULL,
            PRIMARY KEY (`shipment_id`, `product_id`)
          )');
        $this->setVersion(2);
...etc

【讨论】:

如果用户从版本 2 升级到版本 6。您会遍历每个版本 2-6 并在开关 2、3、4、5 和 6 中运行每个 SQL,以便每次升级switch只是从之前版本升级的sql?【参考方案2】:

类似于 gnarf 的建议,我将使用以下内容:

为架构的每次更改创建一个 SQL 文件,运行该文件时会将您从旧版本带到新版本(这可能是每个主要版本一个文件或许多较小的更改)。 创建一个单独的文件,按照它们必须应用的顺序列出每个 SQL 文件名(最旧的在顶部,最新的在底部) 在您的数据库中创建一个简单的“版本控制”表(它只需要一个 VARCHAR 列)

现在您需要编写一个按以下方式工作的简单脚本:

在版本控制表中查询上次应用的 SQL 更新文件的名称 如果有较新的 SQL 更改文件要运行,请按顺序执行它们 记录最新应用的 SQL 文件的名称

我希望这是有道理的

【讨论】:

+1 以获得良好的逻辑。但是如何从 PHP 执行 sql 文件呢? SOURCE file.sql 不适用于 mysqli_real_query!或者你如何编写脚本? 也许你必须爆炸;查找语句(但这很容易破坏)。可以使用 cat /some/deployment-file.sql | mysql ... 的某种不太好的实现【参考方案3】:

尝试使用此工具进行架构迁移:https://github.com/idler/MMP/

【讨论】:

我已经合并了您的注册和未注册帐户,因此您可以完全控制自己的帖子。【参考方案4】:

我用 PHP 为 MySQL 创建了一个小型迁移脚本。它适用于早期项目和那些(还)不需要更复杂的迁移脚本的项目。 https://github.com/kennberg/php-mysql-migrate

【讨论】:

【参考方案5】:

一种方法是使用 mysqldump 将数据库转储到一个大的 sql 文件中。只需获取该文件并在新安装中获取它。

【讨论】:

【参考方案6】:

你不能。你要么

    使用在源环境中执行的所有 sql 编写更新文件,然后执行它们(如上所述),类似于 SVN。需要php脚本执行和sql编写的手动工作

    对两个环境进行后分析并向用户建议应该迁移哪些更新。与第一个基本相同,除了你有一个很大的迁移步骤,而不是很多小块。 SQLyog 可以分析模式和数据的差异。

【讨论】:

【参考方案7】:

您也可以使用免费的 API SqlQuerySync

或为自己创建一个管理 CREATE / ALTER / DELETE 查询的数据库表。

【讨论】:

【参考方案8】:

使用来自@malukenho 的 migratedb https://github.com/malukenho/MigrateDB

【讨论】:

【参考方案9】:

MySQL bench 软件(可以在 mysql 网站上找到)可以做到这一点。但它涉及重复的点击步骤。

【讨论】:

【参考方案10】:

我的目标相同:迁移大型数据库(某些表中超过一百万行)。我正在考虑使用https://phinx.org,这似乎可以很好地处理架构迁移,此外它还带有回滚选项以确保安全。

【讨论】:

【参考方案11】:

你可以试试这个库:mysql-version-control。

我喜欢这个,因为它区分了模式、核心数据和测试数据。但它的使用方式仍然非常容易使用。

【讨论】:

以上是关于如何为 PHP/MySQL 应用程序自动迁移(模式和数据)的主要内容,如果未能解决你的问题,请参考以下文章

如何为实体框架代码优先迁移设置隔离级别

如何为在 docker 容器内运行的 corda 节点运行迁移脚本?

如何为在输入时执行搜索的现有代码创建搜索按钮? php/javascript/mysql

给定文件扩展名,如何为 Ace Editor 自动选择“模式”

MySQL PDO如何为IN()[重复]绑定参数

如何为 laravel 迁移指定文件夹?