A múltkor letöltött adatokat egy cvs file-ba mentettük, és most egy MySQL adatbázist fogunk belőlük építeni. (Ezt megelőzően a szervert telepíteni kell, létre kell hozni egy felhasználót és egy adatbázist, amit most nem részletezek inkább.) Az adatokat két táblába fogjuk szétosztani: az egyikben lesznek az általános adatok, a másikban a tag-ek. Ezt az indokolja, hogy minden torrentet egy-egy adat jellemez az ID, a név, a seederek, leecherek és letöletések számában, kivéve a tag-ek, amikből lehet több is. A másik táblában lesznek így a tag-ek. A két tábla között a torrent azonosítók jelentik majd a kapcsolatot. A csv file egy részlete így néz ki:
1 2 3 4 5 6 |
1488237,Solarstone_-_A_State_of_Trance_Episode_650_(Almaty)_31-01-2014-MiXXedUP,16,0,2014-02-10,21:09:54,44,MP3,EN,Trance 1488233,Monika_Kruse_at_Voodooamt_-_Highway_Number_4_(TERM020)-EP-2002-TR,10,0,2014-02-10,21:07:15,23,MP3,EN,techno 1488232,Kabarématiné_2014.02.08-09.,192,0,2014-02-10,21:06:58,439,MP3,HU,comedy_kabar%C3%A9 1488231,Kayser_-_Read_Your_Enemy,14,0,2014-02-10,21:02:16,27,MP3,EN,groove_thrash_metal 1488230,The_Advent_-_Standers_(CCCB10)-Vinyl-1996-gEm,10,0,2014-02-10,20:58:26,20,MP3,EN,techno 1488226,Dave_the_Drummer_Vs_Glazby_-_Oh_Yeah-(YOLK014)-Vinyl-2005-NRG,7,0,2014-02-10,20:50:24,14,MP3,EN,techno |
Az már látszik, hogy a tag-ekkel nagyon sok bajom lesz... úgy tűnik, hogy a teg-ek nem definiáltak, heterogének, sokszor hiányosak, és azt hiszem, a torzítás elkerülése miatt valahogy ezen segíteni kell. Most egyelőre nem érdekel a dolog. Felépítem az adatbázist, és majd visszatérek a kérdésre. (Ahogy ezeket a mondatokat írtam eszembe jutott, hogy a nemzetközi előadók esetén lehetséges a wikipedia adatai alapján kitölteni a hiányzó tag információkat... a magyarral is lehet próbálkozni, de a magyar wiki nem túl megbízható... de vannak ötleteim! ;-)
Szóval a feltöltő script-ben csatlakozunk az adatbázis motorhoz és megnyitjuk a 'torrent' adatbázist, miközben elvégezzük a szükséges autentikációt:
1 2 3 4 5 6 |
# Open database - the database handler definied as follows: my $dbh = DBI->connect( 'dbi:mysql:torrent', # mysql database, database name 'username', # username 'passwd', # passwd )|| die "Could not connect to database: torrent"; |
Majd létrehozzuk a táblázatokat, ha esetleg nem léteznének eddig. Ezek a loop-ok nyilván csak legelső esetben fognak lefutni.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
my $DataTable = "TorrentData"; # Table that stores torrent data my $TagTable = "Tags"; # Table that stores tags # Creating the table, if it is not existing. my $SQL = $dbh -> prepare ("CREATE TABLE IF NOT EXISTS $DataTable ( ID SMALLINT, Name TEXT, Seeders SAMLLINT, Leechers SMALLINT, U_Time TIME, U_Date DATE, Downloaded SMALLINT, Nationality TEXT, Format SMALLINT )"); $SQL->execute(); $SQL = $dbh -> prepare ("CREATE TABLE IF NOT EXISTS $TagTable ( ID SMALLINT, Tag TEXT, )"); $SQL->execute(); |
A következő kis kódrészlet azt mutatja, hogy csv file egy sorát hogyan bontjuk daraborka, majd építünk egy hash-t, amit aztán az adatbátis építő függvénynek adunk (Előtte persze ki kell törölni a torrentek neveiből azokat a karaktereket, amiket a mysql esetleg parancsként értelmez pl. ',",/ stb.):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
$_ =~ s/\s//g; my @line = split(/,/,$_); # Now let's build a hash with the data, tag data is separated!! my %hash = ( "ID" => $line[0], "Name" => $line[1], "Seeders" => $line[2], "Leechers" => $line[3], "U_Date" => $line[4], "U_time" => $line[5], "Downloads" => $line[6], "Format" => $line[7], "Nationality"=> $line[8] ); # Treat tags separately: my @tags = split("_", $line[9]); &buildDB(\%hash, \@tags); |
Majd soronként szépen végigmegyünk a csv file tartalmán, és feltöltjük az adatbázist. Ügyelünk arra, hogy csak azokat a rekordokat töltse bele, amik még nincsenek az adatbázisban. Ezt az Torrent ID-k lekérdezésével ellenőrizzük. Ez ismét azt a célt szolgálja, hogy a feltöltést valamilyen hiba esetén folytatni tudjuk, illetve elejét veszi annak a hibának, amit az okoz, hogy lehetséges, hogy egy torrent adata kétszer is szerepel a listán. Ez abból adódik, hogy a torrent azonosítókat oldalanként szedtük össze, és folyamat során változhat az adatbázis szerkezete, ami azt okozza, hogy egy-egy torrenttel elcsúszik az egy oldalra kerülő torrentek listája. Remélem kellőképpen bonyorult volt a magyarázat. :D Ez nyilvánvalóvá akkor válik, ha az ember tényleg végiggondolja, hogy mit csinál a bejáró algoritmus. Jézusom... ezzel a folyamatos ellenőrzéssel a feltöltés átkozottul lassú... nem baj, minőségi munkát végzünk :-) Az a baj, hogy a listában előre haladva egyre több és több elemmel kell összevetni a beillesztendő azonosítót, hogy elkerüljük a duplikációt... És ami a legrosszabb, hogy eddig (kb. 5oooo) még nem volt egy duplikáció sem. Nem baj, legalább a rendszer bővíthető marad!! :D
Így néz ki az a függvény, ami ellenőrzi, hogy az adott elem benne van-e az adatbázisban vagy sem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
# Small loop to test if a given record is already in the database or not. sub ExistsOrNot { my $DataBase = $_[0]; # Name of the datebase my $ID = $_[1]; # Identifier of the given record my $Table = $_[2]; # Table to look at. my $flag = "0"; # 0 if does not exist 1 if exists # Test if the ID is already in the database or not. my $record = $DataBase->prepare(qq{SELECT COUNT(1) FROM $Table WHERE ID='$ID'}); $record -> execute(); if ($record->fetch()->[0]) { $flag = "1"; } return $flag; } |
Abban az esetben, ha a függvény visszatérési érétéke 0, azaz az adott azonosítóval még nem szerepel record, akkor azt a következő parancs alapján megteszi:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# if the record is not already inserted in the table, inserted into the corresponding columns. my $sql_statement = "INSERT INTO $DataTable ( ID, Name, Seeders, Leechers, U_Date, U_time, Downloaded, Format, Nationality ) VALUES ( \'$data{ID}\', \'$data{Name}\', \'$data{Seeders}\', \'$data{Leechers}\', \'$data{U_Date}\', \'$data{U_time}\', \'$data{Downloads}\', \'$data{Format}\', \'$data{Nationality}\' )"; # Executing the sql statement. my $ssth = $dbh->prepare($sql_statement); $ssth->execute(); # Inserting Tag data into the database foreach my $tag (@tags){ $sql_statement = "INSERT INTO $TagTable ( ID, Tag ) VALUES ( \'$data{ID}\', \'$tag'\ )"; # Executing the sql statement. my $ssth = $dbh->prepare($sql_statement); $ssth->execute(); } |
Miután a program lefutott nyithatunk egy mysql terminált és ellenőrizhetjük az adatbáztist. A lekérdezés alapján van 73833 torrent, amihez 3544 féle tag megjelölést használtak 118896 esetben (pl. 'vokális trance' és 'viking black folk metal', sőt olyan is van, ahol a vikinget w-vel írta valami nagyokos feltöltő!!! :D). Ez nekem még nagyon sok fejtörést fog okozni, én érzem...
Szóval az adatelemzés előtti utolsó nagy probléma is elhárult! Hamarosan már tényleg belecsapunk a lovak közé!