von weiten reisen, nerdigen skripten und kreativem agenturleben
15 Apr
Folgendes Szenario: Ein Datenbanktabelle enthält alle Bankleitzahlen Deutschlands inklusive der Kurzbezeichnung der Bank. 20.107 Datensätze (Stand 04/2009). Allerdings enthält die Datenbank viele doppelte Datensätze die gelöscht werden sollen um Platz zu sparen.
CREATE TABLE IF NOT EXISTS `bankcode` ( `ID` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT, `Bankleitzahl` VARCHAR(8) NOT NULL, `Kurzbezeichnung` VARCHAR(50) NOT NULL, PRIMARY KEY (`ID`), KEY `Bankleitzahl` (`Bankleitzahl`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='Bankleitzahlen' AUTO_INCREMENT=20108;
Code: SQL-Tabellenstruktur
Eine reine SQL-Möglichkeit, Dubletten zu finden und zu löschen habe ich nicht herausgefunden, deshalb habe ich mir ein kurzes php-Script dazu geschrieben.
Anmerkung: Bei 20.000 Datenbankeinträgen musste ich dazu jedoch die max_execution_time in der php.ini von 60 (Sekunden) auf 320 erhöhen. Ob dies bei einem Produktivsystem sinnvoll ist, sei dahingestellt, das Script lief bei mir lokal auf dem Rechner und ich habe die Änderung somit für gut heißen können.
<?php /** * Dubletten finden und löschen * @author Tobias Fischer / tobias (at) mediaversal (punkt) de * @date 2009-04-12 */ // Datenbankverbindung aufbauen /* ... */ // Anzahl der Datensätze auslesen und ausgeben $result = mysql_query("SELECT `ID` FROM `bankcode`;"); $datensaetze = mysql_num_rows($result); echo 'Datensätze: '.$anzahl.'<br /><br />'; // Arrays erstellen die in den for-Schleifen verwendet werden $dubletten_ids = array(); //zählt die Dubletten eines Datensatzes $overall_ids = array(); // zählt die Gesamtanzahl der Dubletten // Erste Schleife - durchläuft jeden der 20.000 Datensätze einzeln for($i=0;$i< $datensaetze;$i++) { if(!in_array($i, $overall_ids)) { $fid = mysql_result($result,$i,0); $result2 = mysql_query("SELECT * FROM `bankcode` WHERE `ID` = " . $fid . ";"); for($k=0;$k<mysql_num_rows($result2);$k++) { $bcid = mysql_result($result2,$k,0); $blz = mysql_result($result2,$k,1); $kurz = mysql_result($result2,$k,2); // Sucht nach Datensätzen mit gleicher BLZ und gleicher Kurzbezeichnung // AND `ID` <> '".$bcid."' schließt den aktuellen Datensatz aus $result3 = mysql_query("SELECT `ID` FROM `bankcode` WHERE `Bankleitzahl` = '" . $blz . "' AND `Kurzbezeichnung` = '" . $kurz . "' AND `ID` <> '" . $bcid . "';"); // Mache weiter falls Dubletten vorhanden sind if(mysql_num_rows($result3) != 0) { // Durchläuft die Ergebnismenge und speichert alle ID's der gefundenen Dubletten for($m=0;$m<mysql_num_rows ($result3);$m++) { $dubletten_ids[$bcid][$m] = mysql_result($result3,$m,0); } echo '<br />'; echo 'BLZ "'.$blz.'" und Kurzbez. "'.$kurz.'" (ID: '.$bcid.') kommen unter folgenden IDs nochmals vor:'; echo '<br /> '; // Aktuelles Dubletten-ID-Array nochmals durchlaufen und // a) ID's ausgeben // b) jede ID im Array $overall_ids speichern // dies hat den Zweck, dass Datensätze mit dieser ID in der ersten Schleife übersprungen werden // da sonst eine Dopplung vorliegen würde while(list($key,$value) = each($dubletten_ids[$bcid])) { $overall_ids[] = $value; echo '<span '; // Um die Dubletten sofort zu löschen, folgende Zeilen einkommentieren /* $delete = mysql_query("DELETE FROM `bankcode` WHERE `ID` = " . $value . " LIMIT 1;"); if($delete) { echo ' style="color:green;"'; } else { echo ' style="color:red;"'; } */ echo '>'; echo $value; echo ',</span> '; } echo '<br />'; // Frühzeitige Übergabe an den Browser flush(); } } } } echo '<br />'; // Gesamtanzahl aller Dubletten echo count($overall_ids); ?>
Code: PHP-Code-Snippet
Ich konnte damit ca. 12.000 Dubletten aus der BLZ-Tabelle löschen und die Datenmenge somit um mehr als 50 % reduzieren.
Für den Einsatz in einem anderen Datenbank– und Projektumfeld müssen die Datenbankabfragen, die HTML-Textausgaben und eventuell auch einige Variablen angepasst bzw. umbenannt werden!
Ich übernehme keine Gewähr für die Richtigkeit des Skripts und hafte somit auch nicht für eventuell entstandene Schäden durch falschen Einsatz auf Dritt– oder Produktivsystemen!
Hej hej, jag heter Tobias och är tjugofyra år gammal. Das, liebe Freunde der Sprachenkultur, war Schwedisch. Und nochmals auf deutsch: mein Name ist Tobias und ich bin 24 Jahre alt. An der Hochschule der Medien in Stuttgart habe ich acht Semester "Druck- und Medientechnologie" studiert. Anfang 2007 habe ich mich mit [mediaversal] selbstständig gemacht, meinem StartUp das mir die Zeit des Studiums etwas versüßte. Seit April 2011 arbeite ich jedoch festangestellt bei der pagina GmbH und entwickle und gestalte E-Books. Und was sonst noch so los ist erfahrt ihr hier im Blog!
Kommentar hinterlassen