Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Projekt tabel(i) cache dla sklepu
Forum PHP.pl > Forum > Bazy danych
athabus
Witam,

chciałbym w sklepie internetowym wprowadzić nawigację po cechach, która jest obecnie stosowana w wielu sklepach np. cyfrowe.pl rtveuroagd itp.

W skrócie chodzi mi o coś takiego, że klient po wejściu w kategorię produktów typu telewizory może za pomocą filtrów wyszukać te np. o przekątnej 15" i cenie od 2 do 3000 itd.

Macie wiedzę/pomysł jak to zrobić optymalnie?

Na wstępie myślałem o takiej tabeli:

(FK)id_produktu | (FK)id_cechy | wartość cechy

Problem jaki napotykam, to jak wyciągnąć z tej tabeli produkty spełniające np. 3 warunki (dla każdego produktu będzie tyle rekordów ile jest przypisanych do niego cech - w sumie nawet więcej bo niektóre cechy są wielokrotnego wyboru). Czy np. jeśli klient sobie zażyczy telewizor zdefiniowany cechami 32", czarny, Sony, do 5000zł to należy wykonać odpowiednio 4 zapytania - najpierw poszukać wszystkie telewizory 32" z nich wszystkie czarne, z nich te marki Sony itd? Czy może taki problem da się rozwiązać jakoś w miarę elegancko?

Niby problem banalny, ale mam jakieś zaćmienie i nie mogę wymyślić jak to rozwiązać lepiej niż to co opisałem wyżej.

Pozdrawiam i dzięki za pomoc.
nospor
na wyszukiwanie wystarczy jedno zapytanie. Poprostu robisz tyle LEFT JOIN cech po ilu szukasz cech. I dla każdego left join ma być warunek w WHERE:
WHERE c1.id_produktu is not null and c2.id_produktu is not null and.....
melkorm
Hum, LEFT JOIN'y ?

Wydaje mi się że to po prostu jest zwykłe zapytanie z INNER JOIN (produkty na cechy) warunek na cechy na które mamy nałożone warunki i zwykłe AND'y na ich wartości i do tego group by po produktach, pytanie też co z produktami które nie posiadają danych cech smile.gif
athabus
OOO to wydaje mi się ciekawym rozwiązaniem - muszę to przetestować, bo na potrzeby pytania uprościłem trochę problem (produkty jeszcze łączą się w grupy itd), ale wydaj mi się, że to powinno zadziałać.
Wielkie dzięki.

//edit melkorm - akurat produktów bez danej cechy nie będzie, bo wewnątrz kategorii będzie cecha wymagana i nawet jeśli jej nie ma ustawionej, to powstanie rekord null - tak na prawdę ta tabela to będzie cache całego systemu cech, bo będzie też wiele cech niefiltrowalnych itp. Tutaj powstanie taka tabela zawierająca cache tych cech, które można filtrować.
Na szybko jak sobie to układam, to nospor ma chyba rację poniżej, ale coś wolno kojarzę dzisiaj, więc sobie to na spokojnie w wolnej chwili przetestuję.
nospor
@melkorm tak, left joiny. Tyle ile szukasz cech, tyle musisz dać leftjoinów. Nie możesz dać ANDów od tak sobie jak piszesz bo nie zakumałeś problemu wink.gif
melkorm
@nospor, możliwe, jestem lekko wczorajszy i nigdy nie robiłem takiej funkcjonalności, więc możliwe że czegoś nie skumałem, z chęcią zobaczę jakiś przykład to bym ewentualnie poprawił swój tok myślenia wink.gif
nospor
Cytat
Na szybko jak sobie to układam, to nospor ma chyba rację poniżej, ale coś wolno kojarzę dzisiaj, więc sobie to na spokojnie w wolnej chwili przetestuję.
@Athabus rozwiązanie, które ci podałem stosowałem wielokrotnie i zawsze działało wink.gif A stosowałem je dokładnie w tym samym celu co ty i z dokładnie takim samym rozwiązaniem cech dla produktów.

@melkorm nie można tu użyć tylko jednego JOINA na cechy, gdyż każda cecha to oddzielny rekord w tabeli. Nie możesz więc zrobić jedngo JOIN a potem zwykły AND na każdą cechę, gdyż taki warunek nigdy nie będzie spełniony. Jeden rekord nie może być jednoczenie =4 i =8 i =2 wink.gif
athabus
Super, czyli sposób sprawdzony ;-)

Jeszcze raz wielkie dzięki za pomoc, bo bałem się, że utknę na tym pod względem wydajności.
sazian
Cytat(nospor @ 29.10.2012, 15:49:51 ) *
@melkorm tak, left joiny. Tyle ile szukasz cech, tyle musisz dać leftjoinów. Nie możesz dać ANDów od tak sobie jak piszesz bo nie zakumałeś problemu wink.gif


jeśli dobrze zrozumiałem to chcesz zrobić coś takiego
  1. SELECT ...
  2. FROM towary
  3. LEFT JOIN cechy c1 ON ... c1.cechaId=1
  4. LEFT JOIN cechy c2 ON ... c2.cechaId=2
  5. WHERE c1.wartość=1 AND c2.wartość=10


dobrze zrozumiałem questionmark.gif
jeśli tak to ja bym to zrobił inaczej

  1. SELECT t.*
  2. FROM towary t
  3. LEFT JOIN cechy c ON c.towarId=t.towarId
  4. WHERE (c.cechaId= 1 AND c.cechaWartość=1) AND (c.cechaId= 2 AND c.cechaWartość=10)
  5. GROUP BY t.towarId

działa sprawdzone wink.gif i tylko jeden left join
nospor
Cytat
działa sprawdzone
Nie wiem po ilu głębszych to sprawdzałeś, ale o to:
WHERE (c.cechaId= 1 AND c.cechaWartość=1) AND (c.cechaId= 2 AND c.cechaWartość=10)
nie ma racji bytu. Id danej cechy nie może jednocześnie wynosic 1 i 2 smile.gif Tłumaczyłem już to melkormowi
Cytat
Jeden rekord nie może być jednoczenie =4 i =8 i =2
Staraj się czytać wszystko - temat naprawdę jest krótki a wyjaśnienia pisane po polsku wink.gif

A i nie pisz, że coś jest sprawdzone, skoro tego nie sprawdzałeś. Nieładnie tak kłamać wink.gif

Jeśli zaś miałeś na myśli taki warunek:
WHERE (c.cechaId= 1 AND c.cechaWartość=1) OR (c.cechaId= 2 AND c.cechaWartość=10)
to nijak sie on będzie miał do przedstawionego tu problemu smile.gif
sazian
@nospor
ty podły człowieku przez Ciebie aż sprawdziłem jak to nie działa jak działa i okazało się że był błąd w kodzie po stronie php przez co całość "udawała że działa".
I teraz pół kodu musiałem przerabiać Ciebie przerabiać, no dziękuję bardzo biggrin.gif
Ja zdecydowałem się na podzapytania w WHERE, a nie na LEFT JOJN'ach ponieważ mój system wygląda nieco inaczej ale efekt jest ten sam wink.gif


a tak już na zakończenie to przypadkiem danie warunku "cechaWartość=X" w ON nie będzie szybsze niż w WHERE ?
nospor
Cytat
a tak już na zakończenie to przypadkiem danie warunku "cechaWartość=X" w ON nie będzie szybsze niż w WHERE ?
No przecież ja daję właśnie w ON. W where to ja już jedynie sprawdzam czy ID nie jest NULLem smile.gif

Cytat
i okazało się że był błąd w kodzie po stronie php przez co całość "udawała że działa".
W takim razie przepraszam za to "kłamanie" smile.gif

Cytat
I teraz pół kodu musiałem przerabiać Ciebie przerabiać, no dziękuję bardzo
Garnczek miodku i będziemy kwita smile.gif
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.