Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Problem ze strukturą drzewa i uprawnieniami
Forum PHP.pl > Forum > Bazy danych > MySQL
Pilsener
Witajcie, niestety trochę Was pomęcze - mam strukturę zasobów opartą o drzewo:
filmy id 1
-sensacyjne id 2
-dramat id 3
-dla dzieci id 4
--rysunkowe id 5
--fabularne id 6

Każdy zasób ma swoje ID, a tabela wygląda tak:
id||typ_zasobu||id_rodzic||sciezka||glebokosc||nazwa||opis
Np. dla zasobu "fabularne" glebokosc = 2 a sciezka: 1.4 - są to pola pomocnicze ułatwiające zarządzanie całą strukturą -reszta pól nie wymaga chyba komentarza.

Chcę to połączyć z tabelą uprawnień i sprawdzać rodzaj uprawnień dla każdego zasobu (np. edycja, kasacja etc.), tabela uprawnień wygląda normalnie:
login||id_zasobu||edycja||kasacja etc.

Otóż dopiero tu pojawia się problem, bo wymyśliłem sobie, że uprawnienie może mieć 3 statusy: brak, tylko dla danej kategorii oraz dla kategorii niżej - jest to wygodne, bo admin doda zwykłemu użytkownikowi w kategorii "filmy" uprawnienia dla niższych kategorii i nie musi już ich nadawać oddzielnie - MOŻE, ale nie musi, czyli wejdzie sobie do poszczególnych podkategorii i da np:
abc||1||2||... - edycja kategorii "filmy" i wszystkich podkategorii
abc||3||1||... - tylko kategoria "dramat" - bez podkategorii
abc||6||0||... - brak dla kategorii "fabularne" i wszystkich podkategorii
Jest to niezwykle wygodne, ale ma swoją wadę - aby sprawdzić, czy użytkownik ma uprawnienia dla danej kategorii muszę grzebać w kategoriach nadrzędnych, robię to specjalną funkcją, która pobiera ścieżkę typu 1.4.56, rozbija ją i przeszukuje te kategorie - jednak funkcja taka generuje nawet kilkanaście zapytań do bazy i oczywiście należy to przemnożyć razy liczbę zasobów wyświetlanych na stronie, co w sumie może generować nawet kilkaset zapytań worriedsmiley.gif

Moje pytanie brzmi tak - czy da się skontruować takie zapytanie, które "przeszuka" tabelę pobierając uprawnienie na podstawie loginu i id? - przykładowa tabela zasobów, interesują mnie uprawnienia dla zasobu 99:
id||typ_zasobu||id_rodzic||sciezka||glebokosc||nazwa||opis
1||2||||sciezka||0||glowna||glowna
---
99||2||23||1.9.16.23||4||test||test

Natomiast w tabeli uprawnienia mamy:
login||id_zasobu||edycja
abc||9||2
- dozwolona jest edycja zasobu 9 i wszystkich kategorii poniżej - da się zrobić takie zapytanie bez konieczności rozbijania ścieżki i wstawiania jej elementów do zapytań w pętli? Akurat w tym przypadku zapytanie ma zwrócić 2. A np. w tym:
abc||16||1 - 0 (bo nie ma uprawnienia dla kategorii niżej)
abc||99||1 - 1 (bo jest uprawnienie dla tej konkretnej kategorii)
abc||99||2 - 2
Najgorsze w tym jest to, że uprawnienia w kategoriach wyżej mogą być dowolne - trzeba przeszukiwać "od dołu" - jeśli nie ma uprawnienia dla kategorii 99, to szukamy wyżej - dla kateogrii 23 - jeśli i tam nie ma to dla 16, jak są to je pobieramy, niezależnie od uprawnień, które są w kategoriach 1 i 9 - boję się, że zapytaniem do bazy nie da się tego zrobić. Mam nadzieję, że naswietliłem problem dość jasno winksmiley.jpg

Edit: problem częściowo rozwiązałem, wrzucam wszystkie ID kategorii ze ścieżki do zapytania, sortuje, następnie sprawdzam w pętli, jeśli znajdzie uprawnienie w kategorii nadrzędnej to przerywa wykonywanie pętli. Co prawda kod PHP się rozrósł, ale zapytań do bazy mniej - jak ktoś przeczyta i wpadnie na jakiś lepszy pomysł, to będę wdzięczny, pozdrawiam.
mathijas
Hmmm przed chwilą napisałem długi i mądry list, ale na koniec zauważyłem EDITa smile.gif. Widzę, że w miarę uporałeś się z problemem. Moja sugestia jest taka:

- zamiast przesyłania kolejnych zapytań, stwórz funkcję w SQLu. Jeśli boisz się tworzyć pętli w funkcjach SQLowych (nie wiem czemu, ale niektórzy się boją), zastosuj rekurencję. Zaoszczędzisz na czasie dostępu do bazy.

- przerwanie wywołania zapytań po znalezieniu szukanego parametru to podstawa.

- przy takiej strukturze drzewa i ogólnie bazy nie za bardzo da się zaoszczędzić na czymkolwiek czasu - miałem podobny problem niedawno, jak robiłem system skoligowanych kategorii produktów do oscommerce. U mnie wyglądało to tak, że aby wyszukać podobne produkty, należało sprawdzić, do których kategorii jest powiązanie z aktualnej lub jednej z wyższych kategorii - i jeśli jest, to sprawdzić czy powiązanie jest do liścia, czy nie, jeśli nie, to wyszukać liście i stamtąd wyciągnąć produkty... Dość skomplikowane winksmiley.jpg. Z góry wyczuwając smród, sięgnąłem u klienta po specyfikację i przerobiłem w pół godziny całego oscommerce'a pod kątem maksymalnego zagłębienia drzewa kategorii do 3 (korzeń -> gałąź -> liść) i zrobiłem stosowne zapytania na tej podstawie... Ale podejrzewam, że u Ciebie nie da się założyć maksymalnej głębokości lub jest niewygodnie duża?

- jeśli konieczne jest oszczędzanie czasu, najłatwiej to zrobić w tym przypadku na samym przygotowaniu danych przy wyszukiwaniu (okroić maksymalnie ilość wyników, żeby nie leciał w pętli po całej tabeli).

Jak mi coś wpadnie do głowy, dopiszę.
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.