anthonyvipond/deduper-laravel

此包已被废弃且不再维护。未建议替换包。

删除数据库表中的重复记录并重新映射其他表的外键

dev-master 2014-12-29 08:08 UTC

This package is not auto-updated.

Last update: 2022-02-01 12:42:08 UTC


README

目的

  • 从数据库中删除重复记录,并在其他表中重新映射外键

  • 您可以使用一个或多个列轻松定义行的唯一性

  • 它在大表(10M+行)上也能很好地工作。

  • 设计用于直接在生产表上运行

安装

建议通过 composer 进行。

编辑 composer.json 并添加

{
    "require": {
        "anthonyvipond/deduper": "dev-master"
    }
}

安装依赖项

    composer install

config/database.php.sample 复制到 config/database.php 并填写它

现在您应该能够从命令行(dlr文件存储位置)使用程序

php dlr

目的

###删除重复项的表####

假设您有以下 people

id name
2 Mary
3 Joseph
5 Mary
6 mary
7 Joseph
php dlr dedupe tableName columnName

即。

php dlr dedupe people name

您的原始表不会被触及,您将得到这个表 people_uniques

id name
2 Mary
3 Joseph

您还会得到这个表 people_removes

id name new_id
5 Mary null
6 Joseph null
7 Joseph null

但是,如果您有一个表,其唯一性是通过三个列定义的怎么办?没问题。

id firstname lastname birthday
2 Mary Smith 1991-01-01
3 Joseph Parker 1984-02-02
5 Mary Kate 1981-08-08
6 mary kate 2001-03-03
7 Joseph Parker 1984-02-02

在第二个参数中使用 : 分隔列

php dlr dedupe people firstname:lastname:birthday

您将得到一个新的表 people_uniques

id firstname lastname birthday
2 Mary Smith 1991-01-01
3 Joseph Parker 1984-02-02
5 Mary Kate 1981-08-08
6 mary kate 2001-03-03

以及另一个表 people_removes

id firstname lastname birthday new_id
7 Joseph Parker 1984-02-02 null

您可以在不同的列上继续删除重复项。

您的 uniques 表将变小,而您的 removes 表将变大。

再次看看我们表格的最后阶段。

让我们根据新的规则继续删除重复项...

php dlr dedupe tableName firstname:lastname

现在 people_uniques 看起来是这样的

id firstname lastname birthday
2 Mary Smith 1991-01-01
3 Joseph Parker 1984-02-02
5 Mary Kate 1981-08-08

people_removes 看起来是这样的

id firstname lastname birthday new_id
7 Joseph Parker 1984-02-02 null
6 mary kate 2001-03-03 null

###链接####

下一步是将新ID添加到 removes 表中

php dlr link uniquesTable removesTable col1:col2:col3

即。

php dlr link people_uniques people_removes firstname:lastname:birthday

在执行链接时,您应该传入与您在删除时相同的列

如果您多次运行了删除命令,使用了不同的组合,您希望从最不具体到最具体地执行链接

即。

php dlr link people_uniques people_removes lastname:placeOfBirth

php dlr link people_uniques people_removes firstname:lastname:birthday

这样,更具体、质量更高的分组将覆盖质量较低的分组

如果您在多个规则上多次运行了 dedupe 命令,您可能会在运行 link 命令后留下少量未链接的记录

您可以通过传递 --fillerMode 选项用ID填充剩余的 new_id

检查每次运行后有多少 new_id 未重新映射

SELECT count(1) FROM table_removes WHERE new_id IS NULL;

即。

php dlr link people_uniques people_removes firstname:lastname --fillerMode=true

###重新映射####

运行 dedupe 后,您将拥有 table_uniquestable_removes,以及您的原始表。

重新映射要正常工作,需要存在 removes 表。

它不会被写入,但需要被读取。

假设您有以下 teams

id team
2 Knicks
3 Knicks
4 Lakers
5 Knicks

以及需要重新映射的 champions

id team_id
2 3
3 2
4 5
5 2

并且还有teams_uniques表(记住,你已经去重了)

id team
2 Knicks
4 Lakers

还有这个用于重映射的teams_removes

id team new_id
3 Knicks 2
5 Knicks 2

你现在可以重映射指向teams.id的外键

php dlr remap remapTable removesTable foreignKey

即。

php dlr remap champions teams_removes team_id

champions表现在看起来是这样的

id team_id
2 2
3 2
4 2
5 2

在运行remap命令之前,你应该备份重映射表。

如果第一次重映射没有完成,只需再次运行。这不会造成任何伤害。

###替换新表###

回到people表的例子...

完成所有指向people.id的外键的重映射

现在,进行最后的致命一击!

RENAME TABLE table TO table_bak;
RENAME TABLE table_uniques TO table;
DROP TABLE table_bak -- optional

恭喜!你已经去重并重映射了你的表。

贡献指南

  • 发布一个问题!
  • 分支并拉取。

备注

  • 暂时来说,你的原始表必须有一个id
  • 仅适用于MySQL,但我愿意增加更多支持