Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Aktualizacja dostępności produktów
Forum PHP.pl > Forum > PHP
flipp
Witam

Szukam w miarę szybkiego i wydajnego sposobu na aktualizację stanów dostępności produktów w sklepie. U dostawcy generuję plik .csv, w tej chwili 15000 linii, ale z każdym miesiącem produktów jest więcej. Plik formatowany jest w ten sposób:
Kod
SKU produktu, Dostępność
"NAZWA PRODUKTU ABCD 400G", "dostepny"
"NAZWA PRODUKTU DEFG 2kg", "niedostepny"
"NAZWAPROD XYZ 12KG", "dostepny"


W bazie sklepu znajduje się obecnie około 2000 produktów, do każdego przypisany jest unikalny SKU taki jak w hurtowni.
Chcę wybierać kolejno produkty z bazy sklepu, odszukiwać ich SKU w danych z hurtowni i aktualizować status dostępności.
Największym problemem jest szukanie, baza produktów z hurtowni zawiera znacznie więcej produktów niż baza sklepu, nie ma żadnych wspólnych indeksów liczbowych, tylko wspólne nazwy.

Przyszły mi do głowy dwa rozwiązania problemu.
1. Importuje plik .csv do bazy MySQL i przeszukuję według kolejnych SKU produktów ze sklepu. Czy wyszukiwanie FULLTEXT zda egzamin?
2. Przeszukuję plik .csv.

W którą stronę się udać? Może są jakieś inne wydajne rozwiązania, albo cały pomysł jest bez sensu? :]
Pozdrawiam


CuteOne
  1.  
  2. $f = file('file.csv');
  3.  
  4. foreach($f as $k => $v) {
  5.  
  6. if(str_pos('NAZWAPROD XYZ 12KG', $v) !== false) {
  7.  
  8. echo 'znalazłem';
  9. }
  10. }
flipp
Z .csv kombinuję w ten sposób:
  1. $row = 1;
  2. $string = "NAZWA PRODUKTU ABCD 400G";
  3.  
  4. if (($handle = fopen("plik_dane.csv", "r")) !== FALSE) {
  5. while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
  6. $num = count($data);
  7. $row++;
  8.  
  9. if ($string == $data[0]) {
  10. echo "Wiersz " . $row . " Produkt " . $data[0] . " Stan magazynowy " . $data[1];
  11. }
  12. }
  13. fclose($handle);
  14. }


Kwestia co jest bardziej wydajne, mniej bolesne dla serwera? Szukanie w .csv czy w bazie MySQL?
artuross
15k linijek serwer przetrawi sobie spokojnie, MySQL... mysle, ze dzialanie na procedurach zalatwiloby sprawe wydajnosci. Pytanie jak Ty chcesz to zrobic i co jest dla Ciebie lepszym rozwiazaniem, bo naprawde, serwer sobie to przerobi bez problemu.
flipp
Dla mnie to w zasadzie bez większej różnicy czy napisze to pod obsługę pliku czy bazy. Jeśli będę wrzucał z pliku, rozwiązanie zyskuje ten plus, że nie muszę .csv importować do bazy, wystarczy, że wrzucę go na serwer.
Docelowo produktów w pliku będzie nie więcej niż 40k.
artuross
To przerabiaj na plikach, nie ma co sie bawic w baze danych w takim razie. Przetrawienie 40k linijek i znalezienie tego 1000 zajmie mu maksymalnie kilka chwil (chyba, ze na kalkulatorze bedziesz to robil wink.gif)
flipp
Napotkałem kolejny problem. Produkty z bazy sklepu wrzuciłem w pętle for, a wewnątrz for wrzuciłem pętle while, która wyszukuje SKU produktu z bazy sklepu w pliku .csv. Jeżeli jest w ten sposób, wszystko działa, ale przy każdym przejściu pętli for otwiera plik fopen("plik_dane.csv", "r").
Jak to zrobić, żeby nie otwierać pliku kilka tysięcy razy?

  1. <?php
  2. for($index=0; $index < 10; $index++) {
  3.  
  4. $row = 1;
  5. $string = $prodname[$index];
  6.  
  7. if (($handle = fopen("plik_dane.csv", "r")) !== FALSE) {
  8. while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
  9. $num = count($data);
  10. $row++;
  11.  
  12. if ($string == $data[0]) {
  13. echo "Wiersz " . $row . " Produkt " . $data[0] . " Stan magazynowy " . $data[1];
  14. }
  15. }
  16.  
  17. }
  18. }
  19. fclose($handle);
  20. ?>
artuross
http://php.net/manual/en/function.rewind.php

BTW. sprawdzilem wczoraj to, znalezienie 2 000 wynikow wsrod 40 000 rekordow zajelo skryptowi 40 sekund, nie wiem czy Cie to zadowala smile.gif
flipp
Cytat(artuross @ 1.04.2013, 22:33:48 ) *
http://php.net/manual/en/function.rewind.php

BTW. sprawdzilem wczoraj to, znalezienie 2 000 wynikow wsrod 40 000 rekordow zajelo skryptowi 40 sekund, nie wiem czy Cie to zadowala smile.gif


Dziękuję za podpowiedź smile.gif.

Całkiem niezły wynik. Skrypt ma być wykonywany 2-3 razy na dobę, więc nie powinno być tak źle, nawet jak zwiększy się ilość produktów.
artuross
Masz tutaj robacza wersje skrytu, ktory napisalem przed chwila. Dziala... sam zobacz smile.gif Tylko ostrzegam, ponizszy skrypt jest bardzo roboczy (nazwy zmiennych, heh. random wink.gif) Minusem tej opcji jest to, ze produkty w sklepie tez musisz miec w jednym pliku, a nie w bazie danych, ale to mozna na szybko zaimportowac, wykonac to co nizej tylko dostosowane do swoich potrzeb, a na koncu update rekordow jednym plikiem.

  1. <pre>
  2.  
  3. <?php
  4.  
  5.  
  6. $micro = microtime( true );
  7.  
  8.  
  9.  
  10. /* tworzenie pliku z danymi z hurtowni
  11.  
  12. $fp = fopen( 'dane.csv', 'w+' );
  13.  
  14. for ( $i = 1; $i <= 40000; $i++ )
  15. {
  16. fwrite( $fp, '"ABCDEFGJIKL_' . $i . '", "Dostępny"' . "\r\n" );
  17. }
  18. */
  19.  
  20.  
  21.  
  22. $i = 1;
  23.  
  24.  
  25. /* tworzenie pliku z danymi ze sklepu
  26.  
  27. $fp = fopen( 'sklep.csv', 'w+' );
  28.  
  29. for ( $i = 1; $i <= 40000; $i+=20 )
  30. {
  31. fwrite( $fp, '"ABCDEFGJIKL_' . $i . "\"\r\n" );
  32. }
  33. */
  34.  
  35.  
  36.  
  37. /* sprawdzanie czy dostepne #1 */
  38. /*
  39. $a = 1;
  40.  
  41. $f1 = fopen( 'sklep.csv', 'r' );
  42. $f2 = fopen( 'dane.csv', 'r' );
  43.  
  44. while ( !feof( $f1 ) )
  45. {
  46. $l1 = trim( fgets( $f1 ) );
  47.  
  48. if ( empty( $l1 ) )
  49. continue;
  50.  
  51. while ( !feof( $f2 ) )
  52. {
  53. $l2 = fgets( $f2 );
  54.  
  55. if ( strpos( $l2, $l1 ) !== FALSE )
  56. {
  57. echo $i++ . "\n";
  58. }
  59.  
  60. //echo $a2 . "\t\t\t" . $a1 . "\n";
  61. }
  62.  
  63. rewind( $f2 );
  64. }*/
  65.  
  66.  
  67.  
  68. $a = 0;
  69. $f1 = fopen( 'sklep.csv', 'r' );
  70. $f2 = fopen( 'dane.csv', 'r' );
  71.  
  72. while ( !feof( $f1 ) )
  73. {
  74. $x = trim( fgets( $f1 ) );
  75.  
  76. if ( !empty( $x ) )
  77. {
  78. $arr1[] = $x;
  79. }
  80. }
  81.  
  82. while ( !feof( $f2 ) )
  83. {
  84. $a1 = trim( fgets( $f2 ) );
  85. $a1 = explode( ',', $a1 );
  86.  
  87. $arr2[ trim( $a1[ 0 ] ) ] = trim( $a1[ 1 ] );
  88. $a++;
  89. }
  90.  
  91. foreach ( $arr1 as $value )
  92. {
  93. echo $value . ' jest ' . $arr2[ $value ] . "\n";
  94. }
  95.  
  96. //print_r($arr1);
  97.  
  98. echo microtime( true ) - $micro;
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.