Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Składowanie plików w bazie danych
Forum PHP.pl > Forum > PHP
zimi
Zacząłem się zastanawiać własnie nad składowaniem plików w bazie danych, do tej pory myślałem że to rozwiązanie jest co najmniej głupie, jednak w pewnym momencie gdy chciałem napisać klasę zarządzającą plikami doszło do mnie że przy dużej ilości plików aby osiągnąć dobrą wydajność, będę musiał się bawić w tworzenie struktury folderów tak że np. dla pliku o id 15742 ścieżka dostępu będzie wyglądała np. /download/01/57/42/15742.jpg albo w jakichś podobny sposób

z tego co się kiedyś dowiadywałem wynikało że OS bierze sobie dane o jakimś folderze i przeszukuje jeden po drugim w poszukiwaniu wskazanego przez nas pliku, tak więc złożoność liniowa

przy bazie danych i kluczu głównym można podejrzewać złożoność będzie logarytmiczna

chciałbym prosić o opinie i wasze doświadczenia... jakie są wady i zalety takiego rozwiązania
dr_bonzo
Duzo plikow w 1 katalogu i OS/system plikow moze nie wyrobic [zalezy od FS].
A trzymanie tego w bazie - chyba jeszcze gorzej, mega gigantyczna baza, i wydajnosc zapewnie mniejsza niz odczyt prosto z pliku.
zimi
właśnie zastanawia mnie co znaczy to dużo....
głupotą wprawdzie się nie chwali, ale można to też nazwać doświadczeniem smile.gif, napisałem kiedyś serwis który sobie stoi, ma około 10k odświeżeń dziennie, 10k+ obrazków w folderze i przy właściwie każdym odświeżeniu około 30 z nich jest wysyłanych do użytkownika, nie wiem czy to śmiga... wiem że nie muli bo opierdzielu za to jeszcze nie zebrałem... (wiadomo że po drodze jakieś cache itd. ale mimo wszystko problemów nie widać)

robiłem sobie też kiedyś 'benchmark-a' na localu na windzie, czy załadowałem 100 plików czy 10k nie widziałem specjalnie różnicy (albo rezultaty mi się zatarły), jutro zrobię sobie benchmarka na te metody

w każdym razie domyślam się że to nie teoria spiskowa a rzeczywistość, ale co to znaczy dużo?

co do powolnego działania bazy to jestem dość zdziwiony, wiadomo że będzie ogromna bo jak xxxx plików sklei się w jeden to małe to na pewno nie będzie, ale przy wyszukiwaniu indeks, kilka przeskoków i jesteśmy na miejscu nie wiem/nie rozumiem czemu sądzisz że wydajność będzie kiepska

ogólnie jak wspomniałem chciałbym zrobić benchmarka tylko przydałoby się wiedzieć ile to jest dużo...

ponadto chciałbym zapytać o inne negatywy korzystania z bazy z jakimi się spotkaliście
przykładowo przychodzi mi do głowy, że pakowanie jakiejś "paczki" plików na serwerze i wysłanie jej do użytkownika prawdopodobnie nie będzie zbyt wygodne...

PS. co to jest FS?biggrin.gif:P File System?

EDIT: odnośnie benchmarka zastanawiam się czy ma znaczenie jakie pliki wybiorę, ich długości, zawartość, czy np. mogą być wszystkie puste czy to coś zmieni... przy ich wyszukiwaniu
dr_bonzo
hehehe, benczmark na pustych plikach. bez jaj smile.gif Musi byc jak najbardziej odpowiadajacy prawdziwym warunkom. Duzo plikow... 20-100k
i nie ciagle te same, bo sa keszowane na poziomie... dysku? filesystemu?
zimi
tak też myślałem ale wolałem zapytać zanim narobię se roboty... łatwiej stworzyć puste pliki niż czymś wypełnione biggrin.gif:P
no dobra a odnośnie ilości? 1k, 10k, 100k ile to jest "dużo"?

EDIT: źle Ciebie zrozumiałem
Cytat
Duzo plikow... 20-100k

zrozumiałem jako dużo plików o rozmiarze 20-100 KB smile.gif
no dobra to sobie jutro potestuje smile.gif
pytanie o wady i zalety bazy danych do przechowywania plików aktualne smile.gif

EDIT2: Po testach
no dobra opowiem trochę o specyfice benchmarka, jego wynikach i moich pytaniach w związku z nimi O.o

skleconych zostało ~1M plików różnej losowej długości w przedziale 2kB-8kB
test polegał na wybraniu 1000 losowych plików, dla wszystkich przypadków tych samych, zapisaniu ich zawartości do zmiennej i wyznaczeniu długości tej zmiennej

OS: Win XP, FS: NTFS, DB: MySQL, tabela: InnoDB, pola: id (primary key, int), zawartosc (blob)
Struktura katalogów była tworzona w oparciu o identyfikator w ten sposób: (parę przykładów dla różnych identyfikatorów)
5 -> /05.jpg
73 -> /73.jpg
936 -> /09/0936.jpg
4729 -> /47/4729.jpg
83952 -> /08/39/083952.jpg

dla przypadku gdy wszystkie pliki znajdowały się w jednym katalogu adres wyglądał wg schematu: xxx.jpg

chyba wszystko jasne

testowane przypadki:
1. wszystkie pliki w jednym katalogu
2. pliki w bazie danych
3. opisana struktura katalogów

a ) wyniki po pierwszym odpaleniu dla danego ziarna:
1. 28.68 s
2. 11.88 s
3. 40.62 s

b ) po kolejnym uruchomieniu dla danego ziarna:
1. 0.43 s
2. 11.57 s
3. 0.61 s

Wnioski które naszły mnie podczas testów:
- winda ma chłonny cache, mogłem odpalić test z jakimś ziarnem, potem odpalić kolejne 2 (nie sprawdzałem dla większej ilości) testy na innym ziarnie, wrócić do pierwszego i wyniki były jak w przypadku b )
- jestem zawiedzony szybkością bazy danych
- i najdziwniejszy: utworzona struktura katalogów jedynie pogarsza wydajność

Może źle napisałem test, kod podaje poniżej, dla chętnych którzy chcą zweryfikować te wyniki u siebie na localu mogę wysłać skrypty które napisałem w celu wygenerowania tych plików i ułożenia ich w odpowiedniej strukturze, z góry jednak oświadczam że nie biorę odpowiedzialności jeśli jakimś cudem wyrządzą jakieś szkody biggrin.gif:P u mnie przebiegło bez większych problemów smile.gif

Kod nie jest najpiękniejszy, ale nie powinno być problemów z jego analizą:
  1. <?php
  2. $ziarno = 15478;
  3. $do = 970072;
  4. $ile = 1;
  5.  
  6. function name($id)
  7. {
  8. $id = (string)$id;
  9. $dl = strlen($id);
  10. if($dl % 2 == 1)
  11. {
  12. $id = '0'.$id;
  13. $dl ++;
  14. }
  15. $path = 'drzewo';
  16. for($j = 0; $j < $dl - 2; $j++)
  17. {
  18. if($j % 2 == 0)
  19. {
  20. $path .= '/';
  21. }
  22. $path .= $id[$j];
  23. }
  24. $path .= '/'.$id.'.jpg';
  25. return $path;
  26. }
  27.  
  28. echo '<table><tr><td>';
  29. $a = microtime(TRUE);
  30. mt_srand($ziarno);
  31. for($i = 0; $i < $ile; $i++)
  32. {
  33. $zmienna = mt_rand(0, $do);
  34. $dlugosc = strlen(file_get_contents('katalog/'.$zmienna.'.jpg'));
  35. //echo $zmienna.': '.$dlugosc.'<br>';
  36. }
  37. $b = microtime(TRUE);
  38. echo $b - $a;
  39. echo'</td><td>';
  40.  
  41.  
  42. mysql_connect('localhost', 'root', '');
  43. mysql_select_db('pliki');
  44. $a = microtime(TRUE);
  45. mt_srand($ziarno);
  46. for($i = 0; $i < $ile; $i++)
  47. {
  48. $zmienna = mt_rand(0, $do);
  49. $zap = mysql_query('SELECT * FROM pliki WHERE id = "'.($zmienna+1).'"');
  50. $wiersz = mysql_fetch_assoc($zap);
  51.  
  52. $dlugosc = strlen($wiersz['zawartosc']);
  53. //echo $zmienna.': '.$dlugosc.'<br>';
  54. }
  55. $b = microtime(TRUE);
  56. echo $b - $a;
  57. echo'</td><td>';
  58. $a = microtime(TRUE);
  59. mt_srand($ziarno);
  60. for($i = 0; $i < $ile; $i++)
  61. {
  62. $zmienna = mt_rand(0, $do);
  63. $dlugosc = strlen(file_get_contents(name($zmienna)));
  64. //echo $zmienna.': '.$dlugosc.'<br>';
  65. }
  66. $b = microtime(TRUE);
  67. echo $b - $a;
  68. echo'</td></tr></table>';
  69. ?>
dr_bonzo
Hmm,
ze baza jest wolna to chyba oczywiste ;D oprocz odczytu pliku musi przeparsowac SQLke itd, wyslac go do php itd., widocznie narzut SQL jest wiekszy niz korzysc z indeksow.

A co do podzialu na katalogi, hmm, moze jest wolniejsze dla tego ze ciagle wczytuje nowe katalogi, zamiast skorzystac z keszu jednego katalogu, ktory juz zna.

Zreszta, whatever czemu tak a nie inaczej, i tak trzeba wybrac najszybsze rozwiazanie, chyba ze masz inne ograniczenia.
zimi
Cytat
A co do podzialu na katalogi, hmm, moze jest wolniejsze dla tego ze ciagle wczytuje nowe katalogi, zamiast skorzystac z keszu jednego katalogu, ktory juz zna.

w przypadku pierwszego odpalenia nie ma jeszcze cache-u, a i tak działa szybciej biggrin.gif:p

Cytat
Zreszta, whatever czemu tak a nie inaczej, i tak trzeba wybrac najszybsze rozwiazanie, chyba ze masz inne ograniczenia.

no ok najszybsze rozwiązanie najszybszym rozwiązaniem, ale to znaczy że np. allegro które robi strukturę katalogów robi to bo serwy im za szybko chodzą? czy microsoft wymyślił tak genialny system plików że tak jak inne przy 20k plikach mulą tak ntfs śmiga na 1M...

po prostu nieraz słyszałem że taka ilość plików w katalogu to nie do udźwignięcia, a tu się okazuję że działa lepiej niż alternatywne rozwiązania, ale ok
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.