maba/database-inconsistency-finder

这是一个库,可以帮助查找数据库表或不同数据库之间的不一致性

0.1.0 2019-08-07 08:25 UTC

This package is not auto-updated.

Last update: 2024-09-13 08:34:22 UTC


README

Latest Version on Packagist Software License Build Status Coverage Status Quality Score Total Downloads

这是一个库,可以帮助找到孤儿记录(如果它们没有任何指向,则应该删除),对不存在记录的引用,以及对这些记录无效的引用数量。

在什么情况下这可能很有用?

  • 你没有使用外键并且可能有无效的引用。这可能是由于不同的原因
    • 你有几个不同的数据库,例如在分片或使用微服务时;
    • 你没有使用外键以简化数据库结构迁移;
    • 你的应用程序根本不使用外键;
  • 你想要找到孤儿记录。例如,你可以有一个数据库表中的文件,如果没有任何指向此记录的东西,我们希望删除该文件本身。

通常,这些限制应由你的应用程序保证。不幸的是,事情可能会发生,可能会有一些不一致性时不时地出现。

安装

composer require maba/database-inconsistency-finder

配置和用法

$connection = DriverManager::getConnection(['url' => 'mysql://user:secret@localhost/mydb']);
$connection1 = DriverManager::getConnection(['url' => 'mysql://user:secret@db.example.org/otherdb']);

$referencesConfiguration = (new ReferencesConfiguration())
   ->setReferencedColumn(
       (new ReferencedColumn())
           ->setConnection($connection)
           ->setTableName('files')
           ->setIdColumnName('id')
           ->setReferenceNumberColumnName('reference_count')
   )
   ->addTableReferences(
       (new TableReferences())
           ->setConnection($connection)
           ->setTableName('profiles')
           ->setColumnNames(['avatar_file_id', 'cv_file_id'])
   )
   ->addTableReferences(
       (new TableReferences())
           ->setConnection($connection1)
           ->setTableName('documents')
           ->setColumnNames(['file_id'])
   )
;

$inconsistencyFinder = (new Factory())
    ->createInconsistencyFinder($referencesConfiguration)
;

$result = $inconsistencyFinder->find();

if ($result->areInconsistenciesFound()) {
    var_dump(
        $result->getOrphanedRecordIds(),
        $result->getMissingReferenceCounts(),
        $result->getInvalidReferenceCounts()
    );
}

目前所有工作都是同步完成的。你可以通过实现 JobDistributorFactoryInterface 和相关的 JobDistributorInterface 来配置这一点。在这种情况下,自己创建服务树,不要使用 Factory 类。

内部结构

一致性验证以以下方式执行

  • 从数据库中查询 ID 范围(主表中的从-到 IDs)
  • 范围被分成单独的区间,用于工作分配
  • 每个工作都分配给具体的工人
  • 工人通过使用相对较快的数据库 SUM 查询来验证一致性
  • 如果在区间中找到不一致性,则将其分成更小的区间
  • 在每个更小的区间中重复 SUM 查询
  • 对于发现不一致性的区间,运行不一致性查找算法

不一致性查找算法

  • 从数据库中检索所有 ID 和它们对应的引用计数
  • 迭代所有相关表并从其中检索所有 ID
  • 循环检索的数据以查找任何不一致性

这些操作是在内存中执行的,因此在这个阶段间隔已经相当小是很重要的。

一致性验证

通过向数据库发出 SUM 查询来验证一致性。为了避免假阳性,我们选择不是引用计数的总和,而是引用 ID 的 CRC32 值的总和(并且按它们被引用的次数那样多次求和)。

语义版本控制

此库遵循 语义版本控制

有关 API 中可以更改和不能更改的基本信息的更多信息,请参阅 Symfony BC 规则

运行测试

composer update
cd docker
docker-compose up -d
docker exec -it database_inconsistency_finder_test_php bin/phpunit
docker-compose down

贡献

请随意创建问题并提供 pull 请求。

你可以使用此命令修复任何代码风格问题

composer fix-cs