Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Jak skutecznie filtrować duplikaty w bazie
Forum PHP.pl > Forum > Przedszkole
amii
Mam funkcję skanującą pliki w podkatalogu i wyszukującą na podstawie wzorca pewnych wyrażeń w plikach. Następnie funkcja ta dodaję znalezione wyrażenia do bazy i tu pojawia się problem... Nie mogę skutecznie ochronić się przed duplikatami.

UNIQUE KEY ani array_unique nie rozwiązują problemu bo array_unique nie bierze pod uwagę wielkości liter UNIQUE KEY z kolei zwraca na to uwagę. Po za tym UNIQUE KEY przy znalezieniu duplikatu wywala komunikat o błędzie i kończy działanie a mi chodzi tylko o to żeby pominął duplikat prz dodawaniu do bazy. Mimo skanowania każdego pliku array_unique duplikaty mogą się trafiać bo ta funkcja skanuje tylko jeden plik. Jakieś pomysły?



  1. $sql = "CREATE TABLE IF NOT EXISTS tabelka (
  2. id int(11) NOT NULL auto_increment,
  3. rekordy varchar(50) NOT NULL default '',
  4. PRIMARY KEY (id),
  5. UNIQUE KEY uniq_rekordy (rekordy)
  6. )";
  7. $zapytaj = mysql_query($sql) or die('Nie moge sie polaczyc z baza w funkcji zapisz'. mysql_error());
  8.  
  9.  
  10.  
  11. $poszukaj = scandir($katalog); //skanujemy wszystkie pliki w wybranym katalogu domyslnie jest to katalog
  12.  
  13.  
  14.  
  15. for ($i=2; $i<count($poszukaj); $i++) { //obieg petli rowny ilosci plikow w katalogu
  16. $plik = file($katalog.'/'. $poszukaj[$i]); //kazdy plik w katalogu wczytywany jako tablica
  17. $tablica = array_unique($plik); //usun zduplikowane rekordy
  18. for ($a=0; $a<count($plik); $a++) {
  19.  
  20. if ($tablica[$a]=='') { //jesli pusta wartosc nic nie rob
  21. }
  22. else {
  23. $sql = "INSERT INTO tabelka (id, rekordy) VALUES (NULL, '$tablica[$a]')"; //dla kazdej wartosci odczytanej z tablicy zrob zapytanie do bazy
  24. mysql_query($sql) or die('Nie mam dostępu do bazy'. mysql_error());
  25. }
  26. }
  27. }
maly_swd
zamiast insert dajesz:

REPLACE INTO TABELE (nazwa1, nazwa2) VALUES ('vartosc1', 'wartosc2');

to co ma byc unikalne to na to zakladasz klucz unikalnosci;)

UNIQUE KEY uniq_rekordy (id, rekordy)


  1. for ($i=2; $i<count($poszukaj); $i++) { //obieg petli rowny ilosci plikow w katalogu
  2. $plik = file($katalog.'/'. $poszukaj[$i]); //kazdy plik w katalogu wczytywany jako tablica
  3. $tablica = array_unique($plik); //usun zduplikowane rekordy
  4. for ($a=0; $a<count($plik); $a++) {
  5.  
  6. if (!$tablica[$a]=='') { //jesli pusta wartosc nic nie rob
  7.  
  8. $sql = "REPLACE INTO tabelka (id, rekordy) VALUES (NULL, '$tablica[$a]')"; //dla kazdej wartosci odczytanej z tablicy zrob zapytanie do bazy
  9. mysql_query($sql) or die('Nie mam dostępu do bazy'. mysql_error());
  10. }
  11. }
  12. }


poczytaj tez o funkcji glob do zczytania plikow
Zyx
Właściwie nie wiem czy nie lepszym rozwiązaniem byłoby tutaj zapytanie

Kod
INSERT INTO ... ON DUPLICATE KEY UPDATE


Jest pomiędzy nimi dość istotna różnica, mianowicie REPLACE w momencie wykrycia, że chcemy wstawić duplikat, kasuje istniejący wiersz i wstawia nowy, co w pewnych sytuacjach może być bardzo upierdliwe (np. gdy jest on połączony relacjami z czymś innym). Drugie z zapytań jedynie nadpisuje to, co chcemy w istniejącym wierszu bez jego usuwania. Niechaj autor zdecyduje, które rozwiązanie mu bardziej odpowiada.

amii -> tak w ogóle to jakbyś używał jakiegoś przyzwoitego kodu do komunikacji z bazą, a nie jakichś śmietnikowych mysql_query... or die(), mógłbyś bardzo łatwo wychwycić, że rzucany błąd dotyczy umieszczanych w bazie danych, a nie składni zapytania czy połączenia i po prostu go zignorować.
amii
Dzięki dokładnie o to mi chodziło smile.gif Zastosowałem instrukcję ON DUPLICATE KEY UPDATE gdyż nie zwiększa numerów ID.

Zyx a czemu niby to śmieciowe funkcję ? Ja stosuje tą składnie wzorując się na książce PHP5, Apache i MySQL od podstaw.
Zyx
Funkcje, z których korzystasz, są w PHP prawie od początku jego istnienia w niezmienionej formie wraz ze wszystkimi tego konsekwencjami. Z nowszymi wersjami MySQL-a zachowują jedynie kompatybilność, natomiast nie obsługują nowych możliwości tej bazy danych (jak np. podpinanie danych), a na dodatek są źle zaprojektowane. Spójrz sobie sam na kod, który napisałeś:

  1. mysql_query($sql) or die('Nie mam dostępu do bazy'. mysql_error());


Gdybyś nie dopisał or die(), nawet nie potrafiłby on błędów obsługiwać. Uwierz, przerabiałem niedawno projekt pełen takich potworków. Mogłeś zrobić błąd w składniowy w zapytaniu i nawet tego nie zauważyć - wychodziło to dopiero wiele dni później po namysłach w stylu "kurde, czemu to się sypie"? Książki nie zawsze uczą dobrych praktyk - naucz się nawet podstaw programowania obiektowego i zainteresuj się biblioteką PDO. Jest o rząd wielkości wygodniejsza i niezawodna.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.