MySQL DDL触发器,用于列重命名的差异表模式

我正在创建一个PHP脚本来比较两个数据库的模式

我已经设法检查了关于删除/添加的表、列、索引和引用的模式更改,但是当涉及到重命名的列时,我有点卡住了

在下面的示例中,源数据库包含最新的架构,目标数据库包含类似的架构,但可能已过时

先决条件:

  • 我不知道自上次差异以来发生了什么变化
  • 数据库中的数据将不匹配,但架构应位于差异之后

以目标数据库中的以下模式为例

字段类型空键默认额外
field1 int(11)无空值
字段2 int(11)无空值
字段3 int(11)无空值

然后在源数据库中采用以下模式

字段类型空键默认额外
field1 int(11)无空值
字段4 int(11)无空值
字段3 int(11)无空值

在不清楚发生了什么情况的情况下,我无法确定是否通过拖放、后添加或更改列字段2更改为字段4。以下两个查询在表结构方面实现了相同的结果,但使用前者会丢失数据

(1)更改表'demo'DROP'字段2`
ALTER TABLE`demo`ADD`field4`INT(11)在`field1`之后不为空
(2) ALTER TABLE`demo`CHANGE`field2``field4`INT(11)不为空

显然,我可以删除旧列名并创建一个新列名,但这样会丢失原始列中的任何数据。我需要使用altertable TABLE CHANGE COLUMN field new_name结构查询,而不是从表中删除列,然后是更改表
增加列定义

我希望可以使用DDL触发器跟踪模式中的更改,并将这些更改的记录插入源数据库的表中。我可以稍后查询这个表来确定某个列是如何形成的。然而,据我所知,在MySQL中不可能对DDL查询运行触发器,这就排除了记录这些更改的可能性。我在MySQL Forge(现在位于MySQL开发者专区)上读过这个工作日志(WL#2418:DDL触发器),但不幸的是,它似乎仍在等待实现

是否有一种方法可以在不丢失数据的情况下更新表以匹配重命名列的模式

我看过像MySQLDiff这样的东西,但它需要构建到现有的代码中,所以我必须自己构建它

我考虑过的想法

  • 在每一列中添加一条注释,该注释是唯一的数字或字符串(为了参数起见,将其称为散列)。查询information\u schema表以检索此值并在每列上进行比较。如果它是唯一的,则它是一个新列,或者如果它与哈希匹配,但与名称或结构不匹配,则它已被重命名/重新配置

  • 比较模式,如果有一个新列-检查它相对于相邻列的位置。如果新列的名称与缺少的名称位于同一位置,请比较该列的结构。如果匹配,请考虑重命名。如果没有,请考虑删除,然后添加。

更改表格
更改列的旧列名称
新的列名称列定义;

这会在不丢失列中数据的情况下更改列名(除非同时更改数据类型,并且新数据类型小于旧数据类型,例如将BIGINT更改为SMALLINT)

不幸的是,此命令要求您重复列的当前定义,例如数据类型、NOTNULL和其他选项。MySQL中没有简单重命名列的命令

CHANGE COLUMN子句是标准SQL的MySQL扩展,它不提供在适当位置重命名列的语法

如果要坚持使用标准SQL,另一种解决方案是添加新列,将数据从旧列复制到新列,然后删除旧列:

更改表格表格添加列新列名称列定义;
更新表设置新列名称=旧列名称;
更改表格下拉列的旧列名称;

发表评论