Leszek Dąbrowski

Leszek Dąbrowski Financial Systems
Director at JLL

Temat: Przechowywanie plików w bazie SQL

Witam,
zastanaiwam się jak wykonać takowe cud:

Założyłem stronkę do nauki angielskiego, (http://poligloci.pl) i chcę na niej umieścić bazę artykułów. Póki co pracuję nad modułem z artykułami, tzn treść jest w pliku html includowana na stronie głównej.

Chciałbym jednak zrobić tak, że do niektorych artykułów będzie dodawany plik z nagraniem lektora i jakis obrazek. Póki co potrafiłbym to zrobic tylko poprzez przetrzymywanie tych plikow na serwerze i wkladanie ścieżek do nich w samuch artykułach.

A czy da się przechowywac to wszystko w samej bazie (artykuł, plik mp3, zdjęcie). Powiem szczerze, że nie wiem od czego zaczac poszukiwania rozwiązania. Czy temat danych typu blob to dobry kierunek.

jesli macie to poprosze namiary na jakąs stronę o tej tematyce (jak wykonac upload i jak potem wyświetalć wszystko na stronie). W sieci jest dużo gotowych skryptów do galerii zdjęć, ale wolałbym sam poczytac na temat technologii i może uda mi sie coś napisać ręcznie.

z góry dziękuję za pomoc
Łukasz K.

Łukasz K. IT Project
Manager/Team Leader

Temat: Przechowywanie plików w bazie SQL

Witaj Leszku,
wydaje mi się że pomysł zapisywania plików do bazy, tym bardziej że będą to pliki sporej wielkości nie jest dobrym rozwiązaniem. Weź pod uwagę, że taki plik najpierw musi zostać wyciągnięty z bazy i złożony w całość z potem dopiero odtworzony, sam proces odtwarzania pliku video trwa...

Pytanie podstawowe - w jakim celu chcesz to robić? Czy ma to sens?

A szukasz w dobrym kierunku - pola blob w bazach danych właśnie służą do przechowywania tego typu danych.

Pozdrawiam,
Łukasz
Michał Ławicki

Michał Ławicki dostawca zadowolenia

Temat: Przechowywanie plików w bazie SQL

można to zrobić korzystając z pola typu BLOB, ale zdecydowanie lepiej zrobić korzystając z zewnętrznych plików

konto usunięte

Temat: Przechowywanie plików w bazie SQL

Leszek D.:
Witam,
zastanaiwam się jak wykonać takowe cud:

Założyłem stronkę do nauki angielskiego, (http://poligloci.pl) i chcę na niej umieścić bazę artykułów. Póki co pracuję nad modułem z artykułami, tzn treść jest w pliku html includowana na stronie głównej.

Chciałbym jednak zrobić tak, że do niektorych artykułów będzie dodawany plik z nagraniem lektora i jakis obrazek. Póki co potrafiłbym to zrobic tylko poprzez przetrzymywanie tych plikow na serwerze i wkladanie ścieżek do nich w samuch artykułach.

A czy da się przechowywac to wszystko w samej bazie (artykuł, plik mp3, zdjęcie). Powiem szczerze, że nie wiem od czego zaczac poszukiwania rozwiązania. Czy temat danych typu blob to dobry kierunek.

jesli macie to poprosze namiary na jakąs stronę o tej tematyce (jak wykonac upload i jak potem wyświetalć wszystko na stronie). W sieci jest dużo gotowych skryptów do galerii zdjęć, ale wolałbym sam poczytac na temat technologii i może uda mi sie coś napisać ręcznie.

z góry dziękuję za pomoc


Generalnie jako człowiek bogatszy w doświadczenie (to tylko moje założenie) - powiem Panu szczerze, że przechowywanie danych innych niż tekst w bazie jest głupotą. Jest to marnotrawienie wydajności i szybkości bazy. NIE POLECAM w żadnym wypadku zapisu danych takich jak: zdjęcia, obrazki, mp3 (OLABOGA!) w bazie danych!!!

Zamiast tego proponuję wykorzystać katalogi, odrębny dla zdjęć, odrębny dla nagrań i do nich zapisywać dane (ja akurat np. fotki zapisuję pod nazwą hashu md5 z zawartości pliku.rozszerzenie) - to samo zrobiłbym z plikami innego typu. Z tymże nie wiem, jak wtedy php poradzi sobie szybko np. z wygenerowaniem hashu z pliku mp3, ale to akurat zaden problem mozna zostawic nazwy domyslne lub generowac losowe, lub md5(mktime()) i tak dalej i tak dalej.

W tekście natomiast umieszczać odwołania do owych plików, linki, embedded src, czy cokolwiek innego, a dla obrazków <img src> lub po prostu linki i wykorzystanie lightboxa czy czegoś innego eleganckiego.

Dla artykułów format pola LONGTEXT czy TEXT powinien być wystarczający.

Pozdrawiam serdecznie - i radze to dobrze przemyslec, prosze sobie wyobrazic, gdyby wrzuta.pl lub inny serwis z plikami i dzwiekami umieszczal dane w bazie! bylo by to rozwiazanie WYSOCE niewydajne. Pozdrawiam.

konto usunięte

Temat: Przechowywanie plików w bazie SQL

Ja bym dał dla nazwy plików:

(zakładając, że pobierasz z tablicy wielowymiarowej $_FILES nazwę pliku jako $_FILES['userfile']['name'])

$file = substr(md5(uniqid(rand(), true)), 0, 10) . substr($_FILES['userfile']['name'], '-4');

i masz elegancką i unikalną nazwę pliku składającą się z 10 znaków + .rozszerzenie i zapisujesz to w bazie.
Piotr Bandyk

Piotr Bandyk E-commerce,
programowanie

Temat: Przechowywanie plików w bazie SQL

Pliki w bazie - dobre:), już miałem przyjemność oglądać takie cuda (http://kentico.com).

Używajmy rzeczy zgodnie z ich przeznaczeniem.Piotr Bandyk edytował(a) ten post dnia 04.10.07 o godzinie 10:44

konto usunięte

Temat: Przechowywanie plików w bazie SQL

Dodalbym jeszcze, ze jesli plikow ma byc wiecej, to lepiej je rozprowadzic po katalogach, czyli mamy jeden root katalog np. /var/lib/blobs/ a w nim katalogi 0-F zawierajace dalsze katalogi 0-F stosownie. Kernelowi latwiej znalezc plik jak zawartosc katalogu nie za duza.
Leszek Dąbrowski

Leszek Dąbrowski Financial Systems
Director at JLL

Temat: Przechowywanie plików w bazie SQL

Dziękuję za wszystkie rady
Michał Ławicki

Michał Ławicki dostawca zadowolenia

Temat: Przechowywanie plików w bazie SQL

Andrzej D.:
Ja bym dał dla nazwy plików:

(zakładając, że pobierasz z tablicy wielowymiarowej $_FILES nazwę pliku jako $_FILES['userfile']['name'])

$file = substr(md5(uniqid(rand(), true)), 0, 10) . substr($_FILES['userfile']['name'], '-4');

i masz elegancką i unikalną nazwę pliku składającą się z 10 znaków + .rozszerzenie i zapisujesz to w bazie.
to już lepiej korzystać z id rekordu :)

konto usunięte

Temat: Przechowywanie plików w bazie SQL

[author]Michał
Michał Ławicki

Michał Ławicki dostawca zadowolenia

Temat: Przechowywanie plików w bazie SQL

a gdzie tam, wystarczy przyjąć odpowiednią konwencę nazwenictwa. to raczej z generowaniem nazw plików będzie ten problem, że będzie trzeba je gdzieś składować

konto usunięte

Temat: Przechowywanie plików w bazie SQL

Marcin S.:
Dodalbym jeszcze, ze jesli plikow ma byc wiecej, to lepiej je rozprowadzic po katalogach, czyli mamy jeden root katalog np. /var/lib/blobs/ a w nim katalogi 0-F zawierajace dalsze katalogi 0-F stosownie. Kernelowi latwiej znalezc plik jak zawartosc katalogu nie za duza.

Celna uwaga ;-)

Chodzi tutaj o czas dostępu do pliku - im więcej w katalogu plików, tym jest on wolniejszy.

Ja ze swojej strony stworzyłem specjalny algorytm który na podstawie liczby (domyślnie id zasobu) generuje i tworzy odpowiedni ciąg katalogów do umieszczenia w nim pliku z gwarancją, że katalog nie będzie zawierał więcej niż 100 plików i 10 podkatalogów.

Np. dla jakiejś wysokiej liczby ciąg mógłby wyglądać tak:

0/2/8/3/

Dość przydatne przy WIELKIEJ liczbie plików.

konto usunięte

Temat: Przechowywanie plików w bazie SQL

Tomasz Z.:
Marcin S.:
Dodalbym jeszcze, ze jesli plikow ma byc wiecej, to lepiej je rozprowadzic po katalogach, czyli mamy jeden root katalog np. /var/lib/blobs/ a w nim katalogi 0-F zawierajace dalsze katalogi 0-F stosownie. Kernelowi latwiej znalezc plik jak zawartosc katalogu nie za duza.

Celna uwaga ;-)

Chodzi tutaj o czas dostępu do pliku - im więcej w katalogu plików, tym jest on wolniejszy.

Ja ze swojej strony stworzyłem specjalny algorytm który na podstawie liczby (domyślnie id zasobu) generuje i tworzy odpowiedni ciąg katalogów do umieszczenia w nim pliku z gwarancją, że katalog nie będzie zawierał więcej niż 100 plików i 10 podkatalogów.

Np. dla jakiejś wysokiej liczby ciąg mógłby wyglądać tak:

0/2/8/3/

Dość przydatne przy WIELKIEJ liczbie plików.


Podzielisz się algorytmem :) ?

konto usunięte

Temat: Przechowywanie plików w bazie SQL

Tomasz Z.:
Marcin S.:
Dodalbym jeszcze, ze jesli plikow ma byc wiecej, to lepiej je rozprowadzic po katalogach, czyli mamy jeden root katalog np. /var/lib/blobs/ a w nim katalogi 0-F zawierajace dalsze katalogi 0-F stosownie. Kernelowi latwiej znalezc plik jak zawartosc katalogu nie za duza.

Celna uwaga ;-)

Chodzi tutaj o czas dostępu do pliku - im więcej w katalogu plików, tym jest on wolniejszy.

Ja ze swojej strony stworzyłem specjalny algorytm który na podstawie liczby (domyślnie id zasobu) generuje i tworzy odpowiedni ciąg katalogów do umieszczenia w nim pliku z gwarancją, że katalog nie będzie zawierał więcej niż 100 plików i 10 podkatalogów.

Np. dla jakiejś wysokiej liczby ciąg mógłby wyglądać tak:

0/2/8/3/

Dość przydatne przy WIELKIEJ liczbie plików.

i nie daj się prosić :)

konto usunięte

Temat: Przechowywanie plików w bazie SQL

<?

//uploadujemy plik, np. plik.jpg, i mamy jakies insert_id z bazy
//oraz $_FILES

$dir_depth = 2;

// dowlny cast, zeby id z bazy zostalo stringiem
$id = "1234";

if (strlen($id) < 4)
{
// padding, zeby liczby mniej niz 4-cyforwe mialy 4 cyfr
$idpliku = str_pad($id,4,"0",STR_PAD_LEFT);
}

for ($i=1;$i<$dir_depth;$i++)
{
$tmpdir[] = $idpliku{$1};
}

// skladamy nazwe pliku
$plik = "{$idpliku}-{$_FILES['upfile']['name']}";

$path = BLOB_DIR. join("/",$tmpdir);

if (file_exists($path) !== true)
{
mkdir($path, 0700, true);
}

move_uploaded_file($_FILES['upfile']['tmp_name'], "{$path}/{$plik}");

?>

W ten sposob plik z przykladu powinien (nie testowalem tego kodu :>) wyladowac w BLOB_DIR/1/2/1234-plik.jpg. Oczywiscie to podejscei zadziala do 9999 plikow. Stosownie do planowanej ilosci plikow trzeb adobrac $dir_depth.

Jak mowie, nie testowalem, ale cos w ten desen :)Marcin S. edytował(a) ten post dnia 06.10.07 o godzinie 19:29
Michał Minicki

Michał Minicki Doświadczony
programista Java z
szeroką gamą
umiejętności...

Temat: Przechowywanie plików w bazie SQL

Tak na marginesie, to połowę tego kodu możesz spokojnie zamienić na jedną linijkę używając wbudowanych funkcji i nie ograniczając się do głębokości:

<?php

$id = "123456";
$path = implode('/', str_split($id));

konto usunięte

Temat: Przechowywanie plików w bazie SQL

Michał M.:
Tak na marginesie, to połowę tego kodu możesz spokojnie zamienić na jedną linijkę używając wbudowanych funkcji i nie ograniczając się do głębokości:

<?php

$id = "123456";
$path = implode('/', str_split($id));

PHP5 only :) Ale masz racje, choc po prawdzie to:

$id = "123456";
$path = implode('/', str_split(substr($id,0,2)));

zeby pasowalo do zalozen :D

konto usunięte

Temat: Przechowywanie plików w bazie SQL

głupio tak rzgrzewać wątek który zmierza ku końcowi - ale koncepcyjnie:
pytanie myslq czy pliki jest nieco bez sensu bo mysql to pliki. Jeżeli ktoś ma dedyka i ustawia go jak chce to może nie ma różnicy w wydajności ??

konto usunięte

Temat: Przechowywanie plików w bazie SQL

Marcin D.:
głupio tak rzgrzewać wątek który zmierza ku końcowi - ale koncepcyjnie:
pytanie myslq czy pliki jest nieco bez sensu bo mysql to pliki. Jeżeli ktoś ma dedyka i ustawia go jak chce to może nie ma różnicy w wydajności ??

Porada w rodzaju "Jesli Twoj serwis chodzi za slabo zainwestuj w CPU i RAM" nei jest rozwiazaniem probemu tylko leczeniem syfa pudrem, tak samo jak bzykanie na zywo jest lepsze od bzykania w gumce. Oczywiscei sql to pliki, ale zeby wydobyc plik z pola blob trzeba nakarmic resource'ami kernel, webserwer, interperter, klienta sql a na koncu serwer sql. W przypadku pliku lezacego sobie odlogiem w FS wystarczy nakarmic kernel i webserwer. W tym ostatnim przypaku zarlocznosc interpreterea (tu: PHPy) jest marginalna.

Planowanie powinno sie sprowadzic do okreslenie czy przy n requestach moj uklad wytrzyma, czy jak sie rozwine czy uklad wytrzyma 100*n requestow oraz na koniec, czy jak cos sie zwali moj uklad wytrzyma 1000*n requestow. Wtedy sie okaze naprawde, czy dedykowany sql to przechowywania blobow to byl naprawde madrzejszy pomysl od old-fashion pure lazy filesystem :)

W ten sam nieco pokrzywiony sposob mozna zaoszczedzic na dyskach, bo tekst sie ladnie kompresuje i wszystko trzymac w zipach, ktore on-demadn beda rozpakowywane, interpretowane i wysylanie do klienta. Ale czy korzysc z powierzchni rekompensuje zuzycie CPU na wypakowanie?

Po prostu nie uzywajmy metodologii do celow innych niz stworzona :)

konto usunięte

Temat: Przechowywanie plików w bazie SQL

No dobra, niech stracę ;-)

Macie tutaj:

/**
* Pobiera katalog w którym powinien być umieszczony
* plik o id 'fileId'.
*
* W każdym katalogu może być określona, maksymalna liczba plików,
* oraz określona, maksymalna liczba podkatalogów.
*
* Na podstawie 'fileId' są określane katalogi (o dowolnym zagłębieniu).
*
* Jeżeli maxFiles = 100 oraz maxDirs = 10, to plik o id 10001 będzie
* w katalogu (zostanie zwrócone): 0/9/
*/
function getClusterFile($fileId, $maxFiles = 100, $maxDirs = 10, $createDirs = false, $path = "")
{
$rt = "";

if ($createDirs)
{
if (!file_exists($path))
{
mkdir($path);
}
}

if ( $fileId <= 0 || $fileId <= $maxFiles ) return "";

// Reszta z dzielenia fileId / maxFiles
$restId = $fileId%$maxFiles;

$formatedFileId = $fileId - $restId;

// Liczba katalogów jaka jest potrzebna do umieszczenia
// pliku
$howMuchDirs = $formatedFileId / $maxFiles;

while ($howMuchDirs > $maxDirs)
{
$r = $howMuchDirs%$maxDirs;
$howMuchDirs -= $r;
$howMuchDirs = $howMuchDirs/$maxDirs;
$rt .= $r . "/";

if ($createDirs)
{
if (!file_exists($path.$rt))
{
mkdir($path.$rt);
}
}
}

$rt .= $howMuchDirs-1;
if ($createDirs)
{
if (!file_exists($path.$rt))
{
mkdir($path.$rt);
}
}

$rt .= "/";

return $rt;
}

Przykład użycia:

Masz do zapisania plik "file.gif", id zasobu w bazie to 5423, katalog gdzie powinien być składowany plik: /moje_pliki/

$id = 5423; // Lub np. rand(500, 1000000) dla przykładu
$fileToStore = "file.gif";
$baseCatalog = "/moje_pliki/";
$catalog = getClusterFile($id, 100, 10, true, $baseCatalog);
$fullPath = $path.$catalog.$fileToStore;

Przy czym $baseCatalog to raczej powinna być pełna ścieżka - absolutna a nie relatywna, relatywnej użyłem tylko do przykładu.Tomasz Zadora edytował(a) ten post dnia 08.10.07 o godzinie 11:38



Wyślij zaproszenie do