Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySql+PHP] Blob
Forum PHP.pl > Forum > Bazy danych > MySQL
mariopce
Witam

Mam pytanie, ostatnio wdałem się w interesującą konwersacje z Dr. (nie ważne którym ), który powiedział że lepiej przechowywać obrazki (jpg i inne ) w bazie danych niż w systemie plików. Oczywiście że są zalety i wady tego rozwiązania, lecz mnie interesuje prędkość tych rozwiązań. Ogólnie wiadomo że szybciej powinien działać sposób taki:

Zapisujemy obrazek do systemu plików (czyli na dysk twardy) i ścieżkę do bazy danych.
I jak chcemy wyświetlić obrazek na stronie to pobieramy z bazy danych ścieżkę do obrazka, i ładujemy obrazek. Ogólnie to zawsze tak robiłem (mysql + php).

Szukałem co jest lepsze (szybsze), w necie przechowywanie obrazków w BLOBie czy w Systemie plików.
I tutaj jest problem, ogólnie większość programistów piszę że blob jest wolniejszy.
Ale UWAGA exclamation.gif! nigdzie nie podaję linków do jakiś statystyk, porównań czasu.
Przeszukałem setki stron internetowych i nadal nie wiem, co jest szybsze a co wolniejsze i o ile, bo jeśli tylko o 0.00001 s to nie ma co sobie głowę zawracać, ale jeśli o 1 rząd czy o 2 rzędy to już jest problem.
Myślałem że mojego Dr. od razu uciszę argumentem wydajności, i szybkości, jednak nigdzie nie jest czarno na białym napisane, co jest szybsze (wydajniejsze).

2) pytanie, który obrazek zajmie mniej miejsca. Ten w bazie danych, czy w systemie plików.
3) czy obrazek z bazy danych, może być chashowany w przeglądarce. (tzn. z moich eksperymentów, prób - nie ponieważ za każdym odświeżeniem strony jest wczytywany na nowo. Ale może ktoś ma konkretne dane. Porównania czasów)
nevt
co do analizy wydajności... jak myślisz - gdzie baza danych przechowuje swoje dane? w 99% przypadków w systemie plików... czyli ostatecznie i tak dane obrazka pobierane są z dysku twardego. narzut czasu na pozostałe operacje (połączenie z bazą, interpretacja zapytania, wyszukanie danych) jest w obu rozwiązaniach zbliżony. zatem wniosek jest prosty - nie ma istotnej różnicy w wydajności obu metod. przepustowość systemu plików (i bazy danych) jest i tak o kilka rzędów wielkości wyższa niż przepustowość łącza internetowego do serwera, zatem nawet usiłując przetestować rzeczywistą wydajność obu rozwiązań natkniemy się wcześniej na barierę przepustowości łącza.

wg mnie o wyborze jednej czy drugiej metody decyduje nie wydajność a inne parametry: bezpieczeńswto i spójność danych, przenośność projektu miedzy różnymi platformami, uwolnienie się od ograniczeń niektórych systemów plików, częstotliwość zmian w plikach (przy częstej edycji jednak łatwiej gdy mamy pliki w katalogu a nie w bazie...) itp.
mariopce
Dziękuje Ci za odpowiedz,
jednakże to jest znowu tylko pewna teoria nie poparta żadnymi danymi (liczbami).
Na każdej stornie internetowej tak jest:
- wymiana zalet, wad baz danych, systemu plików
i podsumowanie które bierze się z rozumowania autora artykułu notatki.
Nawet na wiki nie ma danych tylko to:
"Typ blob rozpowszechnił się, kiedy w miarę rozwoju technologii dyski twarde stały się coraz większe i coraz tańsze, a komputery znacznie zwiększyły wydajność, jednak stosowanie blobów wciąż nie jest zalecane przez specjalistów".

Skąd mam wiedzieć co tak naprawdę używać, w aplikacji php, java skoro nigdzie nie mam porównania czasów dostępu do danych (plików).
Co jest szybsze ?
A jeśli bazy danych są wolniejsze to o ile są wolniejsze, może są tylko wolniejsze o kilka milisekund, a ponieważ bezpieczeństwo plików w bazie danych jest lepiej zarządzane to może większość programistów nie ma racji, twierdząc że blob nie jest dobry do przechowywania plików binarnych "ponieważ to jest mniej wydajne".

Proszę oto niektóre cytaty i strony z cytatów:
”Niektórzy twierdzą, że nie powinno się przechowywać grafiki w bazie, bo grafika
znacznie obciąża serwer MySQL. Duża ilość obrazków i innych plików faktycznie
potrafi znacznie obciążyć bazę. Czasami jednak trzeba się oprzeć na bazie danych. ”

http://www.diaboli.pl/index.php?site=blob

”Wiem, że ludzie nie polecają umieszczania zdjęć wewnątrz bazy danych
- jednak ja w firmie musiałem i opracowałem skrypt do uploadu zdjęcia do bazy
MySQL oraz sposób wyświetlania zdjęcia.
No ale czasami trzeba robić według wymagań szefa. ”
http://forum.kataloog.info/viewtopic.php?t=14

Z nich jasno wynika że programiści, uważają blob za mniej wydajny (wolniejszy). Spotkałem się z innymi zdaniami krytyki dla ludzi którzy chcieli wykonać skrypt galerii przechowując obrazki w BLOBie, nawet na tym forum smile.gif, ale nie ma konkretnie podanej różnicy ładowania obrazka z bazy danych i z systemu plików.

Ostatecznie zrobiłem swój skrypt który testuje wczytywania plików z bazy danych z kolumny typu blob i z bazy danych ścieżkę, a później z systemu plików.
Niestety na razie źle mi mierzy czas pobrania obrazka z bazy danych a właściwie to mierzy tylko wykonanie wyświetlenia tekstu.
"<img src='skrypt.php'" />

Tak czy siak, po dzień dzisiejszy nie mam pojęcia co jest szybsze, tzn nie mam dowodów że szybsza jest baza danych, i nie mam dowodów że szybszy jest system plików. A Dr. którego mam przekonać żąda dowodów.
Proszę jeśli widzieliście gdzieś w necie, kiedyś pomiar czasu dostępu, pobierania plików z bazy danych i z systemu plików to proszę wklejcie linka.

Jeszcze jedno dodatkowe pytanie:
Jak baza danych pobiera dane z bloba. Tzn są dwie wersje:
1)
a) Otwiera połączenie (lub korzysta z puli połączeń)
cool.gif Wyciąga dane z bloba zapisuje na dysk/bufor
c) zamyka połaczenie
d) przesyła dane z bufora/dysku.

2) Wersja 2
a) Otwiera połączenie (lub korzysta z puli połączeń)
cool.gif Wyciąga dane z bloba i przesyła dane do usera
c) zamyka połaczenie

Dlaczego pytam, ponieważ połączenie do bazy danych kosztuje (ileś ramu, w zależności od wersji bazy danych od kilkukilo do kilkuMB ) jeśli baza danych nie nie musi mieć otwarte połączenie na czas przesyłania danych z bloba to blokuje pule połączeń do bazy.
Jeśli natomiast dane zapisuje najpierw na dysk, i później z niego odczytuje dane, to znowu zastanawia mnie szybkość tego rozwiązania.
A może baza danych pobiera tylko wskażnik początku danych i czyta dane bezpośrednio z dysku twardego.

Masakra, mam jakiegoś pecha do google, pytania nie są proste i oczywiste a wujek google serwuje mi tylko gdybanie. sad.gif
pest
Sprawa rzeczywiście jest dość interesująca i wymagająca przetestowania, może się nawet podejmę czegoś takiego w ciągu najbliższego miesiąca, bo i tak mam sporo benchmarków do zrobienia z Apachem, PHP i MySQL winksmiley.jpg

Tak bez robienia badań, na szybko odpowiem...

co do wersji 1)
Łączysz się z bazą,
  • baza pobiera dane z dysku(odczyt HD),
  • w odpowiedzi zwraca ci dane w zmiennej (RAM)
  • przepisujesz dane ze zmiennej odpowiedzi do innej zmiennej przez np. mysql_fetch_array() - czy zmienna odpowiedzi z MySQL jest automatycznie uwalniana ?, jeśli nie to znowu (RAM)[/li]
  • zapisujesz zmienną na dysk - znowu, po co ją później w ogóle usuwać? (zapis na HD)
  • przeglądarka pobiera normalnie następnym żądaniem plik zapisany na dysku (odczyt HD)
Nie wygląda zbyt efektywnie.

co do wersji drugiej
Czy to w tym samym połączeniu ma pobierać rysunki co i inne dane do strony?
Czy rysunki mają być zagnieżdżone bezpośrednio w HTML'a (chyba coś takiego raz widziałem, ale głowy nie dam)?, jak nie to musisz dać linki do innych plików, które dopiero mają się połączyć do Bazy...

To są na razie przemyślenia, kolejne bez dowodów możesz dodać, ale zobaczymy co z tego wyjdzie.
nevt
Cytat
Skąd mam wiedzieć co tak naprawdę używać, w aplikacji php, java skoro nigdzie nie mam porównania czasów dostępu do danych (plików).
Co jest szybsze ?

Wydawało mi się, że odpowiedziałem ci na to pytanie... Nieistotne, co jest szybsze, bo bez względu na wariant pobrania pliku (baza albo system plików) czas tego pobrania będzie o rząd wielkości MNIEJSZY od czasu jego PRZESŁANIA przez internet. Stąd wybór jednej albo drugiej metody ma MARGINALNY wpływ na szybkość przesłania obrazków do przeglądarki. Żądasz liczb? Proszę bardzo. Typowe dyski z interfejsem SATA oferują przepustowość rzędu 150 Mb/s, a średni czas wyszukiwania jest rzędu 10ms. Plik graficzny o rozmiarze 100kB (kilobajtów), to w rzeczywistości 800kb (kilobitów) czyli 0,8Mb. Zatem czas pobrania tego pliku "do pamięci" jest rzędu 15 ms (10ms wyszukanie, 5ms odczyt). Zakładając, że zgodnie z marudzeniem leniwych programistów odczyt z bazy jest zacznie mniej wydajny (a naprawdę chodzi tylko o to, że trzeba trochę się wysilić i dodatkowego kodu napisać) - niech pobranie z bazy zajmie nam 30ms.

A jaka jest typowa przepustowość łącza internetowego po stronie klienta (użytkownika naszego systemu)? Optymistycznie zakładam, że 2Mb/s. Tym samym przesłanie 100kB obrazka zajmie ok. 0,4 sek. (400ms - teoretycznie, w rzeczywistości ok 1 000 ms). Mam nadzieję, że teraz jasno widzisz, że na wydajność podtawowy wpływ ma prędkość transferu przez sieć, czas pobrania obrazka z pliku lub z bazy jest w zasadzie NIEISTOTNY.

Powodzenia.
mariopce
Hmm, no w sumie logicznie rzecz biorąc masz racje.
Tylko dlaczego 99% wypowiedzi na forach internetowych, na pomysł przechowywania plików graficznych w bazach danych, odradza tego pomysłu ?
[wystarczy w google wpisać: "galeria blob"].
Dlaczego w każdej [ każdej nie czytałem smile.gif ale dużo] książce do PHP od podstaw do zaawansowanej przy przykładzie upladu plików, jest pokazany przykład z uploadem plików na dysk, i wpisaniem ścieżki do bazy danych.
Według mnie to nawet łatwiej jest zapisać plik do bazy danych, niż na dysk.
Hmm. Zrobiłem skrycik który testuje pobieranie z pliku i bazy danych:
  1. <html>
  2.  
  3. <body>
  4.  
  5. <?
  6.  
  7.  
  8. //funkcja do pomiatu czasu 
  9. function getmicrotime(){ 
  10. list($usec, $sec) = explode(" ",microtime()); 
  11. return ((float)$usec + (float)$sec); 
  12. } 
  13.  
  14.  
  15.  
  16.  
  17. //wczytywanie binarki z pola blob kod skryptu view1.php podam niżej 
  18. echo "z bazy danych z pola blob <br />";
  19.  
  20. $start = getmicrotime();
  21.  
  22. echo "<img src=\"view1.php\" />";
  23.  
  24. echo getmicrotime() - $start;
  25.  
  26. echo "<br /><br /><br /><br /><br />";
  27.  
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.  
  35.  
  36. echo "z bazy danch: sposób nazwa pliku <br />";
  37.  
  38. ////////////////////////////
  39.  
  40.  $start = getmicrotime();
  41.  
  42. //Nawiązujemy połączenie z serwerem bazy MySQL
  43. include("sql.php");
  44. //Tworzymy zapytanie wybierające z bazy MySQL zapisanej w niej
  45. //zawartość ścieżki do pliku ,
  46. $sql1="select * from obrazy2 where Id='1'";
  47. $result2=mysql_query($sql1,$conn)
  48. or die ('Błąd wykonania zapytania 1: '.mysql_error());
  49.  
  50. //tworzymy tablicę asocjacyjną $row i wczytujemy do niej
  51. //dane z wybranego rekordu tabeli. W naszym przypadku
  52. //jest to rekord 1.
  53.  
  54. $row = mysql_fetch_assoc($result2);
  55. //Z tablicy $row wydobywamy zawartość komórki "text"
  56. //i zapisujemy ją do zmiennej $grafika.
  57. $grafika=$row['text'];
  58. echo "<img src=\"".$grafika."\" />";
  59. echo getmicrotime() - $start;
  60. echo "<br /><br /><br /><br /><br />";
  61.  
  62.  
  63.  
  64. echo "z bazy nazwa pliku include<br />";
  65. $start = getmicrotime();
  66. include("obrazekzpliku.php");
  67. echo getmicrotime() - $start;
  68. echo "<br /><br /><br /><br /><br /><br /><br /><br />";
  69.  
  70.  
  71.  
  72.  
  73. //zwykłe czytanie z pliku jpg. 
  74. echo "z pliku dysk, bez php<br />";
  75. $start = getmicrotime();
  76. echo "<img src=\"view1.jpg\"/>";
  77. echo getmicrotime() - $start;
  78. echo "<br /><br /><br /><br /><br />";
  79.  
  80.  
  81. ?>
  82. </body>
  83. </html>


  1. <?PHP
  2. include("sql.php");
  3. //Tworzymy zapytanie wybierające z bazy MySQL zapisaną w niej
  4. //zawartość wczytanego wcześniej pliku wraz z jego typem MIME,
  5. //nazwą i rozmiarem.
  6. $sql1="select * from obrazy where ID_obrazy='1'";
  7. //Wykonujemy zapytanie $sql1
  8. $result2=mysql_query($sql1,$conn)
  9. or die ('Błąd wykonania zapytania 1: '.mysql_error());
  10. //tworzymy tablicę asocjacyjną $row i wczytujemy do niej
  11. //dane z wybranego rekordu tabeli. W naszym przypadku
  12. //jest to rekord 1.
  13. $row = mysql_fetch_assoc($result2);
  14. //Z tablicy $row wydobywamy zawartość komórki "obrazek"
  15. //i zapisujemy ją do zmiennej $grafika.
  16. $grafika=$row['obrazek'];
  17. //Z tablicy $row wydobywamy zawartość komórki "typ"
  18. //i zapisujemy ją do zmiennej $typpliku.
  19. $typpliku=$row['typ'];
  20. //Wysyłamy do przeglądarki nagłówek HTTP, informujący
  21. //przeglądarkę że wynik który za chwilę wyświetlimy to
  22. //obrazek w formacie określonym przez zmienną $typpliku.
  23. header("Content-type:$typpliku");
  24. //Drukujemy zawartość zmiennej $grafika,
  25. //czyli wyświetlamy zawartość naszego obrazka
  26. print $grafika;
  27. ?>



  1. <?
  2.  
  3.  
  4.  
  5. //Nawišzujemy połšczenie z serwerem bazy MySQL
  6.  
  7. $conn=mysql_connect("localhost","root","")
  8.  
  9. or die ('Błšd połšczenia z bazš MySQL: '.mysql_error());
  10.  
  11.  
  12.  
  13. //Wybieramy bazę w której mamy tabelę z polem blob
  14.  
  15. $result1=mysql_select_db("data",$conn)
  16.  
  17. or die ('Błšd podczas wyboru bazy: '. mysql_error());
  18. ?>



  1. -- phpMyAdmin SQL Dump
  2. -- version 2.11.4
  3. --
  4. -- Host: localhost
  5. -- Czas wygenerowania: 16 Mar 2008, 23:38
  6. -- Wersja serwera: 5.1.22
  7. -- Wersja PHP: 5.2.3
  8.  
  9.  
  10.  
  11. --
  12. -- Baza danych: `gielda_data`
  13. --
  14.  
  15. -- --------------------------------------------------------
  16.  
  17. --
  18. -- Struktura tabeli dla `obrazy`
  19. --
  20.  
  21. CREATE TABLE `obrazy` (
  22. `ID_obrazy` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  23. `obrazek` mediumblob NOT NULL,
  24. `typ` char(60) NOT NULL,
  25. `nazwa` char(255) NOT NULL,
  26. `rozmiar` int(10) UNSIGNED NOT NULL,
  27. PRIMARY KEY (`ID_obrazy`)
  28. ) ENGINE=MyISAM DEFAULT CHARSET=latin2 AUTO_INCREMENT=3 ;
  29.  
  30. -- --------------------------------------------------------
  31.  
  32. --
  33. -- Struktura tabeli dla `obrazy2`
  34. --
  35.  
  36. CREATE TABLE `obrazy2` (
  37. `Id` int(11) NOT NULL,
  38. `text` varchar(255) NOT NULL,
  39. PRIMARY KEY (`Id`)
  40. ) ENGINE=MyISAM DEFAULT CHARSET=latin2;


Ogólnie cały skrypt działa na www.mariopce.tivi.net.pl/blob/aaa.php

Podałem ten skrypt z 2 powodów:
1) Pokazać łatwość wykonania 2 sposobów dostępu do danych
2) Poprosić was o pomoc z mierzeniem czasu ładowania obrazków z bazy danych, czyli z zewnętrznego skryptu: view1.php.
Funkcja:
  1. <?php
  2. //funkcja do pomiatu czasu 
  3. function getmicrotime(){ 
  4. list($usec, $sec) = explode(" ",microtime()); 
  5. return ((float)$usec + (float)$sec); 
  6. }
  7.  
  8. $start = getmicrotime();
  9. echo getmicrotime() - $start;
  10. ?>

Mierzy tylko czas generowania strony php, bez ładowania zewnętrznych grafik.
3) Żebyście zobaczyli że pliki które pobierane są z bloba nie są cashowane przez przeglądarkę.
tzn. jak wciśniecie 5x F5 to plik graficzny z bloba będzie wczytany z bazy danych,
gdy wczytujemy z bazy danych tylko ścieżkę do pliku, to już jest inaczej, co prawda pobór ścieżki trawa, ale sam plik graficzny jest cashowany..
Chyba że w tym skrypcie popełniłem jakiś błąd ?


Jeśli dane binarne z bloba nie są cashowane przez przeglądarkę to tutaj w tym miejscu byłby największy minus, bloba. Jeśli natomiast ktoś znajdzie skrypt który powoduję ze dane binarne będą cashowane to okaże się że więcej zalet ma blob.

Teraz jeszcze jedno stwierdzenie:
Pliki graficzne można łatwiej zmieniać, np. robić miniaturki. gdy mamy dane zapisane w pliku a nie w bazie danych, [prawda czy fałsz ?]

Ogólnie to im więcej czytam o tym blobie tym więcej nie wiadomych niż wiadomych.
Dziękuje Ci za wyjaśnienie że gardłem dla plików jest sieć internetowa, może więc blob, nie jest taki straszny jak go malują, i powinniśmy przekonywać do używania blobów, zamiast systemu plików które mają wady.
nevt
1. Co do cache przeglądarki - bywa, że jest to cel sam w sobie - wyłączenie cache, żeby mieć 100% gwarancje, że użytkownik widzi aktualna wersję.
2. Blob ma przewagę, gdy musimy zaimplementować skomplikowane mechanizmy dostępu do danych - załóżmy że te obrazki to nie zwykłe graficzki ale skany dokumentów. W systemie plików wszystkie grafiki będą dostępne do odczytu przez przeglądarkę...
3. Kolejny plus dla bloba, jeżeli istnieje potrzeba udostępnienia użytkownikom możliwości aktualizacji / edycji tych plików - system plików jako taki nie ma mechanizmów wspierających rozwiązywanie konfliktów przy jednoczesnej edycji przez wielu użytkowników - a baza danych tak - chociażby poprzez tranzakcje.
4. W sytuacji, gdy potrzebujemy zaimplementować system wersjonowania tych grafik - znacznie prostsze będzie zrobienie tego bezpośrednio w bazie danych.

Podsumowując, uważam, że w typowych zastosowaniach internetowych (elementy layouty, proste ilustracje lub galerie do publikowanych treści) zdecydowanie prostsze jest korzystanie z plików przechowywanych bezpośrednio na dysku. Jednak w przypadku zaawansowanej aplikacji, stawiającej specyficzne wymagania, jak w przykładach powyżej, w NIEKTÓRYCH, sporadycznych przypadkach przewagę zyskuje przechowywanie grafik w bazie danych.

Czyli niewłaściwym pytaniem, jest ogólne: co jest lepsze / wydajniejsze ? pliki czy blob? Właściwym pytaniem jest co jest lepsze / wydajniejsze do implementacji konkretnego zadania ?

Pozdrawiam wszystkich.
Zigi
Częstym powodem dla którego podaje się powód przechowywania obrazków w bazie danych jest większa kontrola dostępu do tych danych, ale mod rewrite daje możliwośc kontrolowania dostępu do plików, które znajdują się na serwerze. I moje pytanie jest nastepujące:

Czy jest możliwośc dynamicznego dawania uprawnień do zobaczenia konkretnych plików? Chodzi o to żeby php dawało argumenty do pliku pliku .httacces i serer decydowałby czy wyslac plik/obrazek do uzytkownika.
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.