Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: zasoby firmy i uzytkownikow
Forum PHP.pl > Forum > Bazy danych > MySQL
nospor
Sytuacja wygląda następująco:
Mamy firmy. W firmie mamy ludzi. Każdy user może dodawać zasoby (czyli poprostu pliki).

Skrocona wersja bazy:
Tabela FIRMA
ID
NAZWA

Tabela USER
ID
ID_FIRM - id firmy do ktorej nalezy
IMIE
....

Tabela ZASOB
ID
ID_USER - id uzytkownika, ktory dodal zasob
SIZE - rozmiar w bajtach zasobu
....


I teraz tak:
Firma ma wykupiony jakiś pakiet, ktory mowi, że w ramach tego pakietu firma może zająć 300MB miejsca. Czyli 300MB zasobow mogą w sumie dodać uzytkownicy tej firmy. W przypadku, gdy te 300MB zostanie przekroczone, to dany user może dodać kolejne zasoby, pod warunkiem, że wykupi własny pakiet np. 100MB.
I tu pojawia się problem:
jak stwierdzić, że dany zasób ma już iść w ramach pakietu użytkownika?

Najprostsze rozwiązanie to takie, by dodawac do jakiegoś pola przy firmie, aktualny stan zasobow. Gdy to pole bedzie mialo wiecej niz 300MB znaczy, ze kolejne zasoby mają iść na konto uzytkownikow. Niestetu to rozwiązanie ma dużo wad, np:
1) Firma zmienia pakiet, podnosi z 300MB do 400MB. Wtedy już nie wiem, ktore zasoby userow będą się miescic w tym pakiecie a ktore nie
2) Dochodzi nowy user, ktory ma już jakąś pule zasobow. Powinny one wg. kolejnosci dodania wskoczyc w pule firmy, a tym samym z puli firmy wyprzeć inne zasoby aktualnych userow, dodane później
3) Odchodzi jakiś user, sytuacji podobna jak wyżej
4) Firma obniża pakiet i znowu podobnie jak w punkcie 1.
5) I pewnie jakieś inne losowe zdarzenia

Wydaje mi się, że powinno się zliczać na bieżąco (tudzież co jakiś czas) od początku aktualny stan zasobow w firmie i gdy ten stan został przekroczony, to dane nadwyzkowe zasoby wrzucac w pule konkretnego usera. Tylko jak znaleźć moment, od którego dane zasoby mają iść poza pulę firmy? Mam jedno zapytanie, ktore niestety do optymalnych nie nalezy, gdyż leci po wszystkich rekordach:
  1. SET @akt=0;
  2. SELECT MAX(ID) FROM (SELECT @akt:=@akt+SIZE ak, ID FROM ZASOB WHERE @akt<300MB ORDER BY ID ASC ) podsel

To wersja uproszczona dla pokazania idei. Dzieki temu zapytaniu dostanę ID pierwszego rekordu, ktory nie miesci się już w puli firmy kazdy zasob wiekszy rowny temu ID ma byc naliczany na konto usera. Tylko jak już pisalem to leci po wszystkich rekordach.

Macie może jakieś inne zapytanie na rozwiązanie tego problemu? A może w ogole inny pomysł na przeliczanie tego wszystkiego?
trueblue
Spróbuj:

  1. SELECT t1.id
  2. FROM zasob AS t1
  3. INNER JOIN zasob AS t2 ON t1.id>= t2.id
  4. GROUP BY 1 HAVING SUM(t2.size)>=300
  5. LIMIT 0,1
nospor
Dla 500tys rekordo zawiesilo mi baze.... Choć i tak uwazam ze moja wersja jest srednio optymalna, to przynajmniej wykonala sie zdecydowanie szybciej. Twoje zapytanie jeszcze sie nie zakonczylo
trueblue
Przepraszam:)
nospor
Nic sie nie stalo smile.gif Kazdy pomysl mile widziany smile.gif
Pyton_000
Dodaj do zasobu flagę określającą przynależność. Oznaczaj czy zasób został dodany w ramach miejsca Firmy czy użytkownika.

I nie wiem czy dobrze zrozumiałem, ale jeżeli użytkownik A miał np. 100MB wykorzystanego prywatnego zasobu i przychodzi do firmy ZZ to po przyłączeniu prywatny zasób zostaje u niego czy przenosi do firmy?
nospor
Gdy user przechodzi do firmy, to powinny się przeliczyć na nowo zasoby w puli firmy z uwzględnieniem zasobow pochodzących od nowo przybyłego. Czyli może być tak, ze przed przenosinami mial z wlasnej puli zuzyte 50MB, ale gdy sie przeniosl do nowej firmy, to wszystko to poszlo w pule firmy a jego prywatna pula jest czysciutka.
I w takim przypadku dodanie flagi na zasoby raczej nic mi nie da, bo i tak musze na nowo wszystko przeliczyć
amii
NIe kombinowałem za wiele z triggerami ale może dało by radę coś w ten deseń ? Pomysł mam taki:
1. Ustawiasz sobie pole o wartości typu true/false w tabeli firma powiedzmy, że nazywa się limit
2. Ustawiasz trigger after dla update, insert i delete dla tabeli zasob
3. W zależności czy suma zasobów (po odpaleniu triggera) dla TEJ firmy przekroczyły 300 zmieniasz wartość pola limit

Cytat
jak stwierdzić, że dany zasób ma już iść w ramach pakietu użytkownika?

User chce dodać zasób, który przekroczy limit dla danej firmy - przed tym sprawdzasz wartość pola limit dla firmy i teorii masz odpowiedź smile.gif
nospor
@amii chyba nie czytales tego:
Cytat
Najprostsze rozwiązanie to takie, by dodawac do jakiegoś pola przy firmie, aktualny stan zasobow. Gdy to pole bedzie mialo wiecej niz 300MB znaczy, ze kolejne zasoby mają iść na konto uzytkownikow. Niestetu to rozwiązanie ma dużo wad, np:
1) Firma zmienia pakiet, podnosi z 300MB do 400MB. Wtedy już nie wiem, ktore zasoby userow będą się miescic w tym pakiecie a ktore nie
2) Dochodzi nowy user, ktory ma już jakąś pule zasobow. Powinny one wg. kolejnosci dodania wskoczyc w pule firmy, a tym samym z puli firmy wyprzeć inne zasoby aktualnych userow, dodane później
3) Odchodzi jakiś user, sytuacji podobna jak wyżej
4) Firma obniża pakiet i znowu podobnie jak w punkcie 1.
5) I pewnie jakieś inne losowe zdarzenia
Przecież to co zaproponowaleś jest niemalże identyczne i ma dokladnie takie same wady jakie wypisalem.
Pyton_000
Jeszcze pytanie, czy pakiety prywatne są przenośne między fimami?

Czyli User A ma 200MB w których ma już coś wrzucone, odchodzi z firmy A do B i tam też ma ten pakiet z tą samą zawartością.
nospor
Tak, pakiet uzytkownika jest jego prywatnym pakietem niezaleznym od firmy. Jedyna zaleznosc jaka zachodzi to taka, ze jak jedna firma ma mniejszy swoj pakiet i user w tej firmie musial wykorzystac 30MB swojego pakietu, to gdy przejdzie do innej firmy to moze sie okazac, ze tam wszystkie jego zasoby mieszczą się jeszcze w pakiecie tamtej firmy i z jego prywatnego pakietu zwalnia sie te 30MB
zaajcu
A czy prywatny zasób np dla Jan Kowalski to jest jego całkowicie prywatny czy jest to zasób dla Jan Kowalski pracujący w firmie X?

Jeżeli całkiem prywatny to nie wiem po co automatyczne przenoszenie zasobów z kąta prywatnego na konto firmowe. Chyb, że to ma działać tak, że jeżeli w firmie x brak miejsce to grzecznościowo Jan Kowalski udostępnia trochę swojego miejsca na trzymanie pliku firmowego.

I tu pytanie kiedy Jan Kowalski się przelogował z konta firmowego na konto prywatne?

Jeżeli natomiast konto JK traktujemy jako konto wykupione przez firmę to inna bajka.
nospor
Uzytkownicy danej firmy wpierw zuzywają pakiet danej firmy. W momencie, gdy pakiet firmy się wyczerpał, a ktoś prywatnie ma większe potrzeby, to dokupuje własny pakiet za wlasne pieniądze.

"Firma" to pojęcie umowne. Równie dobrze jako firma może być traktowana uczelnia, która wykupuje jakiś tam pakiet na podstawowe potrzeby. Gdy ktoś jednak będzie miał wieksze i zostaną zuzyte zasoby pakietu uczelni, to ktoś dokupuje sobie własny prywatny
gitbejbe
Cytat
I teraz tak:
Firma ma wykupiony jakiś pakiet, ktory mowi, że w ramach tego pakietu firma może zająć 300MB miejsca. Czyli 300MB zasobow mogą w sumie dodać uzytkownicy tej firmy. W przypadku, gdy te 300MB zostanie przekroczone, to dany user może dodać kolejne zasoby, pod warunkiem, że wykupi własny pakiet np. 100MB.
I tu pojawia się problem:
jak stwierdzić, że dany zasób ma już iść w ramach pakietu użytkownika?


uzytkownik wykupując sobie dodatkowe miejsce w danej firmie, tworzy swój własny zbiór zasobów. Jeśli skończy się pakiet dla uzytkownika to te rzeczy które on wrzucił w ramach tego pakietu zostaną również zablokowane/usunięte - dlatego powinny te dane być trzymane w oddzielnym miejscu. Dlatego tworzysz dodatkową tabele dla pakietów użytkowników przypisanych do konkretnych firm. Każda firma ma swój jakiś limit, jeśli zostanie od przekroczony a dany użytkownik chce coś dodać, to sprawdzasz czy jest on powiązany z ta firmą, jaki pakiet posiada i czy ma na nim miejsce.
nospor
@gitbejbe ale nadal nie rozwiązuje to przeliczania miejsca, chocby w przypadku gdy firma zmieni pakiet np. na wiekszy

edit:
no dobra, zalozmy, ze zapytanie, ktore podalem na poczatku:
  1. SET @akt=0;
  2. SELECT MAX(ID) FROM (SELECT @akt:=@akt+SIZE ak, ID FROM ZASOB WHERE @akt<300MB ORDER BY ID ASC ) podsel

jest ok. Zapytanie to znajduje ID zasobu, ktore nie lapie sie juz w pakiet firmy.

Ale zalozmy, że firma określa, że kazdy user może w ramach jej pakietu zuzyc max 10MB zasobow. Ma to uniknac sytuacji, że jeden user zuzyje caly pakiet firmy. No i tutaj powyzsze zapytanie się już nie nadaje do niczego... Jakieś propozycje jak to poprawić?
Pyton_000
Musisz określić dla pakietu firmowego quota_per_user i podczas dodawania sprawdzać czy SUM(user_files) < quota_per_user.
nospor
No dobrze, tyle to ja wiem. Tylko jak to wplesc w podane wyzej zapytanie?
zaajcu
A może zmienić trochę koncepcje.

Użytkownik wykupuje sobie dany pakiet, ale wewnątrz danej firmy.

Tabele bym zrobił tak:

pakiety
id | firma_id | user | max
1 | 1 | null | 200
2 | 1 | 1 | 100
3 | 1 | 2 | 50

pliki
id | pakiet_id | size
1 | 1 | 20
1 | 1 | 30
1 | 2 | 2
1 | 3 | 14
1 | 2 | 21
1 | 1 | 75

W tedy liczysz jak chcesz wg pakietów.
nospor
To raczej nie rozwiązuje opisanych tu problemow.

Dobra, tak czy siak poddałem się. Będę to zliczał na poziomie php. Tam zrobie wszystko jak chce.
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.