Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP][MySQL] Przechowywanie rozmiaru pliku, Jak optymalnie przechowywać rozmiar pliku przesłanego na serwer?
krzywy5830
post 10.01.2017, 11:58:43
Post #1





Grupa: Zarejestrowani
Postów: 38
Pomógł: 5
Dołączył: 14.10.2012

Ostrzeżenie: (0%)
-----


Piszę sobie dysk internetowy, coś jak google drive. Pliki będą przechowywane na dysku, natomiast informacje o pliku takie jak jego nazwa i tak dalej będą przechowywane w bazie danych (w tabeli files). Jeden użytkownik ma mieć możliwość wrzucenia maksymalnie tylko np. 1 GB danych (administrator będzie miał możliwość konfiguracji, będzie można ustawić w pliku konfiguracyjnym ile maksymalnie miejsca na dysku może zająć użytkownik). Dodatkowo chcę mieć możliwość wyświetlenia użytkownikowi rozmiaru każdego pojedyńczego pliku. Aby to zrobić muszę gdzieś zapisywać rozmiar plików. Wpadłem na następujące rozwiązania:

1. Przechowuję rozmiar każdego pojedyńczego pliku w bazie danych jako integer (w bajtach) w tabeli files, aby sprawdzić ile miejsca zajmuje dany użytkownik to liczę sumę rozmiarów wszystkich plików danego użytkownika odpowiednim zapytaniem MySQL (SELECT SUM(size) FROM files WHERE uid = 69, gdzie uid to ID użytkownika, do którego należą pliki a size chyba nie muszę tłumaczyć).

2. Przechowuję rozmiar każdego pojedyńczego pliku w bazie danych jako string (np. 21 KB, 148 GB, 71,21 MB) w tabeli files i dodatkowo przechowuję sumę rozmiaru wszystkich plików danego użytkownika jako integer w bajtach, w tabeli users.

3. Nie przechowuję rozmiaru plików w bazie danych, natomiast pobieram ją za każdym razem za pomocą PHP korzystając np. z DirectoryIterator. Musiałbym wtedy pobrać z bazy danych wszystkie pliki, które należą do danego użytkownika a potem przejechać przez nie DirectoryIteratorem. Moim zdaniem bez sensu.

Zastanawiam się, które rozwiązanie jest najbardziej optymalne i sensowne. A może macie jeszcze jakieś pomysły?
Go to the top of the page
+Quote Post
nospor
post 10.01.2017, 14:28:17
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




oczywiscie ze nr1. Skad pomysl na pozostale 2?


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
viking
post 10.01.2017, 14:48:09
Post #3





Grupa: Zarejestrowani
Postów: 6 378
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


3 przecież nie jest złe. Katalogi mogłyby być id użytkownika. Wtedy tylko proste du na katalogu i jest rzeczywisty rozmiar.


--------------------
Go to the top of the page
+Quote Post
Puszy
post 10.01.2017, 15:08:08
Post #4





Grupa: Zarejestrowani
Postów: 279
Pomógł: 42
Dołączył: 10.10.2011

Ostrzeżenie: (0%)
-----


Cytat(viking @ 10.01.2017, 14:48:09 ) *
3 przecież nie jest złe. Katalogi mogłyby być id użytkownika. Wtedy tylko proste du na katalogu i jest rzeczywisty rozmiar.


Bezsensowne podejście, chcesz za każdym odświeżeniem "panelu" aby skrypt liczył rzeczywistą wartość? Jeżeli już musisz wykonać to w ten sposób to cacheuj tę wartość i odpalaj nowe cacheowania przy każdej akcji użytkownika takiej jak add/delete/update.
Go to the top of the page
+Quote Post
viking
post 10.01.2017, 15:16:19
Post #5





Grupa: Zarejestrowani
Postów: 6 378
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Nawet gdyby to było w ten sposób robione, to będzie i tak 1000x szybsze niż sumowanie na bazie. du będzie też wewnętrznie cache'owany przez system.

Ten post edytował viking 10.01.2017, 15:21:53


--------------------
Go to the top of the page
+Quote Post
nospor
post 10.01.2017, 15:29:15
Post #6





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Jakim cudem nr3 ma byc szybsze od 1? Przeciez on w nr 3 pobiera wpierw z bazy liste wszystkich plikow...


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
Puszy
post 10.01.2017, 15:40:35
Post #7





Grupa: Zarejestrowani
Postów: 279
Pomógł: 42
Dołączył: 10.10.2011

Ostrzeżenie: (0%)
-----


Cytat(viking @ 10.01.2017, 15:16:19 ) *
Nawet gdyby to było w ten sposób robione, to będzie i tak 1000x szybsze niż sumowanie na bazie. du będzie też wewnętrznie cache'owany przez system.


Chcesz mi powiedzieć że zwykły SELECT sumujący jedną kolumnę będzie chodził wolniej niż DirectoryIterator?
Go to the top of the page
+Quote Post
viking
post 10.01.2017, 16:25:42
Post #8





Grupa: Zarejestrowani
Postów: 6 378
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


A czy ja gdziekolwiek pisałem o DirectoryIterator?


--------------------
Go to the top of the page
+Quote Post
nospor
post 10.01.2017, 16:27:50
Post #9





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Pisales o nr3, ktore to jest DirectoryIteratorem.
Fakt, wspomniales tez potem o du na folderze co zmienia postac rzeczy

Nie mniej jednak oryginalny nr3 jest do bani.
A i wartosci rozmiar plikow jest rownie dobrze trzymac w bazie tak jak trzymane beda nazwy


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
viking
post 10.01.2017, 16:31:57
Post #10





Grupa: Zarejestrowani
Postów: 6 378
Pomógł: 1116
Dołączył: 30.08.2006

Ostrzeżenie: (0%)
-----


Nr 3 jest: np. z DirectoryIterator. Drobna różnica wink.gif


--------------------
Go to the top of the page
+Quote Post
nospor
post 10.01.2017, 16:34:12
Post #11





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Musiałbym wtedy pobrać z bazy danych wszystkie pliki, które należą do danego użytkownika a potem przejechać przez nie DirectoryIteratorem.

Nadal uwazasz ze pobranie wszystkich plikow z bazy i potem sprawdzenie ich rozmiaru na dysku jest lepsze niz proste SUM na bazie? wink.gif
To mam na mysli ze oryginalny nr3 jest do bani. wink.gif


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
krzywy5830
post 10.01.2017, 17:04:19
Post #12





Grupa: Zarejestrowani
Postów: 38
Pomógł: 5
Dołączył: 14.10.2012

Ostrzeżenie: (0%)
-----


Też uważam, że nr 3 jest bez sensu. Waham się między 1 i 2, wszystko zależy od tego ile w bazie danych zajmuje VARCHAR a ile INT, przy czym maksymalna liczba jaką można zapisać na UNSIGNED INT to 4294967295, co oznacza, że pojedyńczy plik mógłby mieć rozmiar tylko 4 GB bo więcej mi się w bazie nie zmieści. Musiałbym użyć BIGINT, który zajmuje 8 bajtów. Zatem przy opcji nr 1 mam kolumnę o rozmiarze 8 bajtów dla każdego pliku. Przy opcji nr 2 muszę zrobić kolumnę BIGINT w tabeli users, która przechowuje sumę wszystkich rozmiarów pliku w bajtach oraz kolumnę VARCHAR(9) w tabeli files, która przechowuje rozmiar pojedyńczego pliku wraz z jednostką (np. "999,99 MB"). Zatem mam kolumnę o rozmiarze 8 bajtów dla każdego użytkownika plus +-9 znaków dla każdego pliku. Bazę mam kodowaną w UTF8 i o ile się nie mylę 1 znak zajmuje 1 bajt, więc VARCHAR(9) zajmuje +- 9 bajtów. To chyba opcja nr 1 będzie najbardziej rozsądna. Dobrze myślę? Pytanie też jak długi byłby czas wykonywania zapytania SELECT SUM(size) FROM files WHERE uid = 69 przy dużej ilości rekordów.
Go to the top of the page
+Quote Post
trueblue
post 10.01.2017, 17:11:23
Post #13





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Alternatywą dla opcji 2 są dwa pola DECIMAL (XXX,XX) + TINYINT lub ENUM dla jednostki.


--------------------
Go to the top of the page
+Quote Post
krzywy5830
post 10.01.2017, 17:24:54
Post #14





Grupa: Zarejestrowani
Postów: 38
Pomógł: 5
Dołączył: 14.10.2012

Ostrzeżenie: (0%)
-----


Cytat(trueblue @ 10.01.2017, 17:11:23 ) *
Alternatywą dla opcji 2 są dwa pola DECIMAL (XXX,XX) + TINYINT lub ENUM dla jednostki.


DECIMAL zajmuje chyba 8 bajtów (nie jestem pewny) a TINYINT i ENUM 1 bajt, co daje razem 9 bajtów. Wyjdzie na to samo co przy VARCHAR(9) tongue.gif
Go to the top of the page
+Quote Post
trueblue
post 10.01.2017, 17:40:46
Post #15





Grupa: Zarejestrowani
Postów: 6 806
Pomógł: 1828
Dołączył: 11.03.2014

Ostrzeżenie: (0%)
-----


Jeśli dobrze liczę to DECIMAL(5,2) zajmie 5 bajtów.
Nie chcesz DECIMAL, to MEDIUMINT.


--------------------
Go to the top of the page
+Quote Post
Pyton_000
post 10.01.2017, 20:07:00
Post #16





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Ale macie dylematy....

Wpis w tabeli files unsigned int (co daje nam ~4GB pliki) - trzymasz rozmiar w bajtach.
Dodatkowo możesz pokusić się w tabeli users o sumę plików (ustawiasz trigger na BD w files co by dodawał/odejmował od sumy w users) i nawet nie musisz mielić tabeli files.

mielenie dyskiem jest bez sensu skoro można to załatwić optymalniej.
Go to the top of the page
+Quote Post
krzywy5830
post 11.01.2017, 10:00:16
Post #17





Grupa: Zarejestrowani
Postów: 38
Pomógł: 5
Dołączył: 14.10.2012

Ostrzeżenie: (0%)
-----


Cytat(Pyton_000 @ 10.01.2017, 20:07:00 ) *
Wpis w tabeli files unsigned int (co daje nam ~4GB pliki)


A co jeśli użytkownik zechce wrzucić plik, który zajmuje 5 GB tongue.gif? Myślę, że BIGINT powinien być. A o triggerach poczytam, nie wiedziałem, że takie bajery można robić.
Go to the top of the page
+Quote Post
nospor
post 11.01.2017, 11:00:05
Post #18





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Toz sam napisales ze user bedzie mial limit na sume wszystkich 1GB a teraz nagle chcesz mu pozwolic na plik 5GB... Miejze litosc tongue.gif



--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
Pyton_000
post 11.01.2017, 11:02:27
Post #19





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Może być i BigInt, nie zrobi Ci to różnicy. Zawsze też możesz zaokrąglać rozmiary plików do pełnych KB dzięki temu zawsze to kilka bajtów do przodu biggrin.gif
Go to the top of the page
+Quote Post
krzywy5830
post 11.01.2017, 11:08:14
Post #20





Grupa: Zarejestrowani
Postów: 38
Pomógł: 5
Dołączył: 14.10.2012

Ostrzeżenie: (0%)
-----


Cytat(nospor @ 11.01.2017, 11:00:05 ) *
Toz sam napisales ze user bedzie mial limit na sume wszystkich 1GB a teraz nagle chcesz mu pozwolic na plik 5GB... Miejze litosc tongue.gif


Nie prawda, napisałem:

Cytat(krzywy5830 @ 10.01.2017, 11:58:43 ) *
np. 1 GB danych (administrator będzie miał możliwość konfiguracji, będzie można ustawić w pliku konfiguracyjnym ile maksymalnie miejsca na dysku może zająć użytkownik)


Dobra, dzięki wszystkim za pomoc, chyba zdecyduję się na rozwiązanie Pyton_000.
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 13.07.2025 - 00:43