我正在开发一个项目,用户可以将 Excel 文件上传到 MySQL 数据库。这些文件是我们数据的主要来源,因为它们直接来自与公司合作的承包商。它们包含大量行(每个文件平均 23000)和每行 100 列!
我目前面临的问题是同一文件可能被某人(承包商或公司)更改,并且在重新上传时,我的系统应该检测更改、更新实际数据并保存操作(单元格从一个值变为另一个值的事实 :: oldValue -> newValue) 因此我们可以返回并运行版本比较(例如 3 次重新上传 === 3 个版本)。 (oldValue Version1 VS newValue Version5)
我开发了一个用于保存更改的小机制 => 我有一个表来保存导入数据(每次用户导入文件时,都会在此表中插入一个新行)和另一个用于保存实际更改的表>
我保存了有一些变化的行的id,以及实际数据被修改的id和表(上传一个文件会导致插入多个表,所以每当发生变化时,我需要知道发生在哪个表中)。我还保存了新值和旧值,这将帮助我恢复“档案数据”。
- 要恢复版本:SELECT * FROM 'Archive' WHERE idImport = ${versionNumber}
- 要恢复一行的版本:SELECT * FROM 'Archive' WHERE idImport = ${versionNumber} and rowId = ${rowId}
- 要恢复一行的所有版本:SELECT * FROM 'Archive' WHERE rowId = ${rowId}
- 恢复一张表的版本:SELECT * FROM 'Archine' WHERE tableName = ${table}
- 等
现在有了这个结构,我正在努力恢复一个版本或在两个版本之间运行比较,这让人觉得我想出了一个错误的方法,因为它很难完成这项工作!我想知道以前是否有人这样做过,或者有什么好的方法?
事情变得非常混乱的情况:
- 在一个版本中更改的行在另一个版本中可能没有更改(我正在使用时间机器在发生这种情况时在其他版本中进行搜索)
- 两个版本中的行都发生了变化,但不是相同的字段。 (假设我们有一个用户表,第 2 次和第 5 次上传时 id 为 15 的用户的数据发生了变化,太好了!现在对于第二个版本只更改了名称,但是对于第五个版本他的地址被更改了!比较这些时两个版本,我们会在构造我们的数据数组时遇到问题。名称来自“some”-> NULL(名称从不为空。第 5 个版本中没有名称更改)和地址来自 NULL ->“some”显然是错误的).
我的实际方法(php)
<?php
//Join records sets and Compare them
foreach ($firstRecord as $frecord) {
//Retrieve first record fields that have changed
$fFields = $frecord->fieldName;
//Check if the same record have changed in the second version as well
$sId = array_search($frecord->idRecord,$secondRecord);
if($sId) {
$srecord = $secondRecord[$sId];
//Retrieve straversee fields that have changed
$sFields = $srecord->fieldName;
//Compare the two records fields
foreach ($fFields as $fField) {
$sfId = array_search($fField,$sFields);
//The same field for the same record was changed in both version (perfect case)
if($sfId) {
$sField = $sFields[$sfId];
$deltaRow[$fField]["oldValue"] = $frecord->deltaValue;
$deltaRow[$fField]["newValue"] = $srecord->deltaValue;
//Delete the checked field from the second version traversee to avoid re-checking
unset($sField[$sfId]);
}
//The changed field in V1 was not found in V2 -> Lookup for a value
else {
$deltaRow[$fField]["oldValue"] = $frecord->deltaValue;
$deltaRow[$fField]["newValue"] = $this->valueLookUp();
}
}
$dataArray[] = $deltaRow;
//Delete the checked record from the second version set to avoid re-checking
unset($secondRecord[$srecord]);
}
我不知道如何处理这个问题,正如我所说,我正在研究一个值查找算法,所以当在一个版本中找不到数据时,我会尝试在这两个版本之间找到它,这样我就可以构建我的数据数组。如果有人能提供一些提示、想法和改进,我会非常高兴,这样我就可以继续前进。
谢谢!