如何在MySQL表中合并两个冗余记录,保持所有PK/FK关系?

Mik*_*ley 8 php mysql merge redundancy foreign-keys

假设我有一个customers包含以下字段和记录的表:

id   first_name   last_name   email                  phone
------------------------------------------------------------------------
1    Michael      Turley      mturley@whatever.com   555-123-4567
2    John         Dohe        jdoe@whatever.com      
3    Jack         Smith       jsmith@whatever.com    555-555-5555
4    Johnathan    Doe                                123-456-7890
Run Code Online (Sandbox Code Playgroud)

还有其他一些表,如orders,rewards,receipts其中有外键customer_id有关此表的customers.id.

正如您所看到的,我的用户以他们无限的智慧为John Doe创建了重复记录,并且拼写和数据丢失都不一致.管理员注意到这一点,选择客户2和4,然后单击"合并".然后提示他们为每个字段选择哪个值是正确的等等,我的PHP确定合并的记录应如下所示:

id   first_name   last_name   email                  phone
------------------------------------------------------------------------
?    John         Doe         jdoe@whatever.com      123-456-7890
Run Code Online (Sandbox Code Playgroud)

让我们假设Doe已经下了几个订单,获得了奖励,生成了收据..但是其中一些已经与id 2相关联,有些已经与id 4相关联.合并的行需要匹配其他所有外键与原始行匹配的表.

这是我不知道该怎么做的地方.我的直觉是这样做:

DELETE FROM customers WHERE id = 4;

UPDATE customers
SET first_name = 'John',
    last_name  = 'Doe',
    email      = 'jdoe@whatever.com',
    phone      = '123-456-7890'
WHERE id = 2;

UPDATE orders, rewards, receipts
SET customer_id = 2
WHERE customer_id = 4;
Run Code Online (Sandbox Code Playgroud)

我认为这样可行,但如果稍后我添加另一个具有customer_id外键的表,我必须记得返回并将该表添加到我的合并函数中的第二个UPDATE查询,否则可能会失去完整性.

必须有更好的方法来做到这一点.

bor*_*rel 6

我来到这里形式谷歌这是我的2美分:

SELECT `TABLE_NAME` 
FROM `information_schema`.`KEY_COLUMN_USAGE` 
WHERE REFERENCED_TABLE_SCHEMA='DATABASE'
  AND REFERENCED_TABLE_NAME='customers'
  AND REFERENCED_COLUMN_NAME='customer_id'
Run Code Online (Sandbox Code Playgroud)

为保险添加数据库(你永远不会知道有人复制数据库).

我们不是查找列名,而是查看外键本身

如果更改了删除限制以限制在删除/迁移子项之前无法删除任何内容


sre*_*mer 0

作为我的评论的更新:

use information_schema;
select table_name from columns where column_name = 'customer_id';
Run Code Online (Sandbox Code Playgroud)

然后循环遍历结果表并进行相应更新。

就我个人而言,我会使用您本能的解决方案,因为如果存在包含需要豁免的 customer_id 列的表,这可能会很危险。