Minulla on hakemistossa läjä kuvia ja niitä tulee sinne satunnaisesti lisää. Haluaisin tallentaa kaikista tiedot kantaan helpompaa jäsennystä varten.
Mitenhän kannattaisi toteutta sellainen, että kun haluan päivittää tietokannan, niin vain sellaisten kuvien tiedot tallennetaan mitä ei ole vielä käsitelty? PHP:llähän voisi tarkistaa ennen jokaista inserttiä onko kyseinen kuva jo kannassa, mutta kyselyitä tulisi aika julmetusti. Mikä olisi siis fiksumpi keino?
Helpoin tapa mielestäni on tälläinen:
<?php //Avataan tämä kansio $hakemisto = opendir("."); while($tieto = readdir($hakemisto) { //yksinään $tieto on tiedoston nimi //Jos ollaan hakemassa tätä tai edellistä kansiota, niin continue if($tieto == "." OR $tieto == "..") continue; //Tarkistetaan onko tieto jo kannassa $hae = mysql_query("SELECT * FROM kuvat WHERE nimi = '$tieto'"); //Jos tuloksia ei ollut if(mysql_num_rows($hae) == 0) { //Laitetaan tiedot kantaan mysql_query("INSERT INTO kuvat(nimi) VALUES('$tieto')"); } } ?>
Ensin määritetään kansio, joka käydään läpi. Sitten käydään kansion tiedostoja niin kauan läpi, että on käyty kaikki läpi. Haetaan kannasta kuvaa nimeltä $tieto. Jos ei löytynyt, niin lisätään se kantaan.
Miten niin kyselyitä tulisi julmetusti? Tietenkin joka kuvan kohdalla pitää tarkistaa, että onko se kannassa, mutta ei niitä kyselyitä nyt tietenkään erikseen pidä jokaista kirjoittaa.
Jep, tavallaan noin tuo minunkin koodini toimii (siitä puuttuu vain kyselyt).
Kyseessä on kuitenkin valvontakameran tallentamat kuvat, joita arvatenkin on aika paljon (tuhansia). Itsestäni vain tuntuu, että noita kyselyitä voisi jollain vähentääkin...
Jos kuvia ei ole kannassa kovin paljon, voit hakea ne yhdellä kyselyllä etukäteen ja tehdä tarkistuksen PHP:n puolella. Toisaalta toistuvakaan SELECT-kysely ei ole aivan huono ratkaisu.
Tehokas vaihtoehto on tutkia kuvien viimeistä muutosaikaa, jonka saa tiedostosta filemtime-funktiolla UNIX-aikaleiman muodossa. Jos siis tallennat tämän ajankin kantaan, voit hakea ennen tiedostojen tutkimista viimeisen muokkausajan ja lisätä kaikki kuvat, joita on muokattu tämän jälkeen. (Huonon tuurin välttämiseksi voi olla järkevää tarkistaa SELECTillä vielä nekin kuvat, joiden aika on sama kuin viimeisin muokkausaika; voihan olla, että hakemistoon ilmestyy uusi kuva juuri silloin, kun kuvia lisätään tietokantaan, ja tämä uusi kuva jääkin sillä kertaa laittamatta.)
Tästä saattaisi olla apua:
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
Itse käyttäisin Insert lauseen yhteydessä NOT EXISTS -ehtoa.
Jotenkin näin:
INSERT INTO kuvat(nimi) VALUES('$tieto') WHERE NOT EXISTS (SELECT * FROM kuvat WHERE nimi = '$tieto')
Jep, hyviä ajatuksia kaikki. Pitää miettiä mikä näistä olisi paras vaihtoehto. Nuo ehdolliset insertit ovat ainakin todella kätevän oloisia, jos en niitä tässä käytä, niin jossain jatkossa varmasti...
Kiitti kaikille!
Hycken ehdotus ei sinänsä vähennä kyselyiden määrää, vaan ehtolause vain siirtyy PHP:ltä MySQL:n puolelle. Joka tapauksessa tehdään siis ensin SELECT ja sitten tarvittaessa INSERT. Jos kuvasta tallennetaan kantaan paljon tietoja (esim. koko kuvadata), tuo vaihtoehto on jopa hitaampi, koska MySQL-palvelimelle lähetetään aivan turhaan kaikki data vanhoistakin kuvista. Myös ajv:n ehdotus kärsii jälkimmäisestä ongelmasta, ja koska UPDATE-vaihtoehtoa ei ilmeisesti edes kaivattu, myös ihan tavallinen INSERT tekisi tehtävänsä, kunhan taulussa vain on jokin yksilöivä kenttä, jolla estetään saman tiedon lisäys moneen kertaan.
Aihe on jo aika vanha, joten et voi enää vastata siihen.