删除不在.csv文件中的DB记录 - 效率?

时间:2012-06-06 09:08:39

标签: php mysql oop csv

我目前正在开发一个导入议程项目(例如事件)的.csv导入,并将它们放在MySQL数据库中。我已经掌握了它的工作原理,然而有一段麻烦的代码,我似乎无法解决它如何解决它或使其更有效/更好。

对我来说很麻烦的代码部分是每个小时都会举行一个事件 - tuesdaysunday2012-06-01'到2013-04-01并且你想要检查这些值中是否有一些已经在DB中(因为用户可能会再次使用一些调整后的值导入.csv文件)。我当前的代码最终在DB中实现了正确的值,但是它的完成方式有点麻烦。如果再次导入文件,那么周日的所有值都会被删除,因为我的检查会在周二的第二个周期进行,这将检查数据库值是否与星期二生成的值匹配。检查完成后,将值插入到数据库中,我的foreach会检查星期日的所有值(星期二不会被删除,因为我保留了一个包含所有先前插入值的数组),然后再次插入它们。 所以基本上当我导入.csv文件时,它会删除然后插入相同的值,我的问题是如何防止这种情况?

此外,如果您认为有任何方法可以改进此代码(因为我觉得首先开始时效率不高)请说出来,非常感谢。

以下是检查重复事件的代码,如果您需要任何澄清或其他代码,请告诉我们:

//REPEAT DAYS OF THE WEEK
if(!empty($repeatDayOfTheWeek) && $repeatDayOfTheWeek != '')
{
    $daysOfTheWeek = explode(',', $repeatDayOfTheWeek);

    foreach($daysOfTheWeek as $key => $dayOfTheWeek)
    {
        if(!is_numeric($dayOfTheWeek))
        {
            continue;
        }

        unset($agendaI->agendaItemValues['stopDate']);

        $beginDate = strtotime($tempStartDate);
        $endDate = strtotime($tempStopDate);

        $dayDates = array();
        $arrayDatesInDb = array();

        if(!isset($previousInserts))
        {
            $previousInserts = array();
        }

        if($beginDate != '' && $endDate != '')
        {
            while($beginDate <= $endDate)
            {
                if(date('N', $beginDate) == $dayOfTheWeek)
                {
                    $dayDates[] = date('Y-m-d', $beginDate);
                }

                $beginDate = strtotime("+1 day", $beginDate);
            }

        $datesInDb = $agendaI->getAgendaItemsByExternId($externId);

        if(empty($datesInDb))
        {
            foreach($dayDates as $dayDate)
            {
                dump("Empty DB - INSERT: ".$dayDate);
                $agendaI->setAgendaItemValue('startDate', $dayDate);
                $agendaI->saveAgendaItem();
                $previousInserts[] = $dayDate;
            }
        }
        else
        {
            dump('DB with records');
            foreach($datesInDb as $dateInDb)
            {
                if(!in_array($dateInDb->startDate, $dayDates) && !in_array($dateInDb->startDate, $previousInserts))
                {
                    dump("Not in Item-array, but in DB - DELETE: ".$dateInDb->startDate);
                    $agendaI->deleteAgendaItem($dateInDb->id);
                }
            }

        foreach($dayDates as $dayDate)
        {
            foreach($datesInDb as $dateInDb)
            {
                if($dayDate == $dateInDb->startDate)
                {
                    $arrayDatesInDb[] = $dateInDb->startDate;
                    dump("In array & in DB - UPDATE: ".$dateInDb->startDate);
                    $agendaI->setAgendaItemValue('id', $dateInDb->id);
                    $agendaI->saveAgendaItem();
                    $previousInserts[] = $dayDate;
                }
            }
        }

    unset($agendaI->agendaItemValues['id']);

    foreach($dayDates as $dayDate)
    {
        if(!in_array($dayDate, $arrayDatesInDb))
        {
            dump("Not in DB-array but in Item-array - INSERT: ".$dayDate);
            $agendaI->setAgendaItemValue('startDate', $dayDate);
            $agendaI->saveAgendaItem();
            $previousInserts[] = $dayDate;
        }
    }
}

以下字段位于.csv中:

"Datum" "Tijdstip" "Evenement" "Locatie" "Website" "Toelichting" "Duits" "engels" "startdatum" "stopdatum" "herhalen dag van de week" "externid" "categorie" "via"

换句话说
我需要检查数据库中的记录是否与.csv中的记录相同。如果csv没有DB的记录,我需要从DB中删除它(我当前的代码就是这样做,效率不高)

2 个答案:

答案 0 :(得分:1)

您可以在UNIQUEstartdatumstopdatum列中定义herhalen dag van de week索引,而不是在PHP中实施检查。然后使用REPLACELOAD DATA命令将这些字段上匹配的任何现有记录替换为新记录:

ALTER TABLE events ADD UNIQUE INDEX (startdatum, stopdatum, dag);

LOAD DATA INFILE '/path/to/foo.csv'
  REPLACE
  INTO TABLE events;

答案 1 :(得分:0)

我最终通过以下方式解决了这个问题,而没有使用foreach为每个$ daysoftheweek并使用array_diff:

            //REPEAT DAYS OF THE WEEK
            if(!empty($repeatDayOfTheWeek) && $repeatDayOfTheWeek != '')
            {
                $daysOfTheWeek = explode(',', $repeatDayOfTheWeek);

                $agendaI->setAgendaItemValue('stopDate', '');

                $beginDate = strtotime($startDate);
                $endDate = strtotime($stopDate);
                $dayDates = array();
                $dbValues = array();
                $dbValues['datum'] = array();
                $latestDbValues = array();
                $toBeDeletedKeys = array();

                while($beginDate <= $endDate)
                {
                    if(in_array(date('N', $beginDate), $daysOfTheWeek))
                    {
                        $dayDates[] = date('Y-m-d', $beginDate);
                    }

                    $beginDate = strtotime("+1 day", $beginDate);
                }

                $evenementenInDb = $agendaI->getAgendaItemsByExternId($externId);

                if(!empty($evenementenInDb))
                {
                    foreach($evenementenInDb as $evenementInDb)
                    {
                        $dbValues['agendaid'][] = $evenementInDb->id;
                        $dbValues['datum'][] = $evenementInDb->startDate;
                    }
                }

                foreach($dayDates as $dayDate)
                {
                    $key = array_search($dayDate, $dbValues['datum']); 
                    if($key !== false && is_numeric($key))
                    {
                        //UPDATE
                        $agendaI->setAgendaItemValue('id', $dbValues['agendaid'][$key]);
                        $agendaI->setAgendaItemValue('startDate', $dayDate);
                        $agendaI->saveAgendaItem();
                        $latestDbValues[] = $dayDate;
                        dump('UPDATE');
                    }
                    else
                    {
                        //INSERT
                        unset($agendaI->agendaItemValues['id']);
                        $agendaI->setAgendaItemValue('startDate', $dayDate);
                        $agendaI->saveAgendaItem();
                        $latestDbValues[] = $dayDate;
                        dump('INSERT');
                    }
                }

                $toBeDeleted = array_diff($dbValues['datum'], $latestDbValues);
                foreach($toBeDeleted as $value)
                {
                    $toBeDeletedKeys[] = array_search($value, $dbValues['datum']);
                }

                foreach($toBeDeletedKeys as $toBeDeletedKey)
                {
                    //DELETE
                    $agendaI->deleteAgendaItem($dbValues['agendaid'][$toBeDeletedKey]);
                    dump('DELETE');
                }
            }
            else 
            { 
                //Normal, non repeating event
                //INSERT
                if(!empty($agendaItem) && is_numeric($agendaItem->id))
                {
                    $agendaI->setAgendaItemValue('id',$agendaItem->id);
                }

                $agendaId = $agendaI->saveAgendaItem();
            }