Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> [SQL] Wyświetlanie rekordów
sadistic_son
post
Post #1





Grupa: Zarejestrowani
Postów: 1 495
Pomógł: 245
Dołączył: 1.07.2009
Skąd: Bydgoszcz

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


Mam 2 tabele w bazie:

Wiadomosci:
id_w
od_kogo
do_kogo
tekst

Userzy:
id_u
nazwa

Kiedy user wysyła wiadomość (np. user o nazwie AAA i id=1 do usera BBB o id=2) to w tabeli wiadomości zostanie dodany rekord o wartości pól: od_kogo=1 i do_kogo=2:
  1. INSERT INTO wiadomosci VALUES( NULL , '1' , '2' , 'tekst' )


Moje pytanie brzmi jak wyświetlić te wiadomości tak aby zamiast id userów pojawiły się ich nazwy. Normalnie nie miałem z tym problemów bo robiłem to tak:
  1. SELECT userzy.nazwa , wiadomosci.tekst FROM wiadomosci , userzy WHERE userzy.id = wiadomosci.od_kogo
Ale tutaj jest problem bo przecież pola od_kogo i do_kogo oba są wartościami id z tabeli userzy. Jak skonsrtuować zapytanie aby SQL nie zgłupiał?


Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi
thek
post
Post #2





Grupa: Moderatorzy
Postów: 4 362
Pomógł: 714
Dołączył: 12.02.2009
Skąd: Jak się położę tak leżę :D




Nie wiadomości.przeczytane tylko w.przeczytane, bo aliasem jest w - nie wiadomości. Jeśli dodatkowo chcesz ograniczyć to zapytanie to wystarczy do WHERE dodać kolejny warunek. Jeśli chcesz sprawdzić jakie są nieprzeczytane wiadomości od usera X to dodajesz od LIKE '$user' lub w.od_kogo = $user_id (to da ten sam efekt), a jeśli chcesz sprawdzić jakich wiadomości user X nie przeczytał to walisz do LIKE '$user' lub w.do_kogo = '$user_id' (znów zamiennik).
Czyli ostatecznie masz w wariantach:
a) wiadomości nieprzeczytane wysłane przez użytkownika $user (gdy jako login) lub $user_id (gdy znamy tylko jego id)
  1. SELECT w.id_w, u1.nazwa AS od, u2.nazwa AS do, w.tekst FROM wiadomosci w LEFT JOIN userzy u1 ON w.od_kogo = u1.u_id LEFT JOIN userzy u2 ON w.do_kogo = u2.u_id WHERE w.przeczytane = 0 AND od LIKE '.$user.' ORDER BY w.id_w DESC


  1. SELECT w.id_w, u1.nazwa AS od, u2.nazwa AS do, w.tekst FROM wiadomosci w LEFT JOIN userzy u1 ON w.od_kogo = u1.u_id LEFT JOIN userzy u2 ON w.do_kogo = u2.u_id WHERE w.przeczytane = 0 AND w.od_kogo = '.$user_id.' ORDER BY w.id_w DESC


(IMG:style_emoticons/default/cool.gif) wiadomości nieprzeczytane przysłane dla użytkownika $user (gdy jako login) lub $user_id (gdy znamy tylko jego id)
  1. SELECT w.id_w, u1.nazwa AS od, u2.nazwa AS do, w.tekst FROM wiadomosci w LEFT JOIN userzy u1 ON w.od_kogo = u1.u_id LEFT JOIN userzy u2 ON w.do_kogo = u2.u_id WHERE w.przeczytane = 0 AND do LIKE '.$user.' ORDER BY w.id_w DESC


  1. SELECT w.id_w, u1.nazwa AS od, u2.nazwa AS do, w.tekst FROM wiadomosci w LEFT JOIN userzy u1 ON w.do_kogo = u1.u_id LEFT JOIN userzy u2 ON w.do_kogo = u2.u_id WHERE w.przeczytane = 0 AND w.do_kogo = '.$user_id.' ORDER BY w.id_w DESC

Oczywiście $user i $user_id są zmiennymi php, które musisz wpleść w składnię zapytania. Od, do, w.od_kogo, w.do_kogo i w.przeczytana można mieszać w WHERE tworząc odpowiednie układy. Zauważ, że używając od i do, musisz użyć pojedynczych apostrofów i LIKE, gdyż mamy do czynienia ze zmienną tekstową. Dawno nie robiłem porównań dla tekstówek więc od = '$user' może zadziałać (choć nie sądzę), ale musiałbyś sprawdzić. Na pewno przeszukiwanie po id będzie szybsze bo masz tam ustawione indeksy, więc drugie warianty powinny działać szybciej. LIKE jest wolniejszy, a tutaj dodatkowo kolumna na której działa (login) nie ma indeksu.

Co do pytania ostatniego to chyba już się wyjaśniło z kodem powyżej. W warunku dajesz
  1. WHERE do LIKE 'admin'


Nie mam ochoty wywoływać flame'a. Tym bardziej, że nie znamy wielkości tabel zarówno wiadomości jak i userów oraz typu bazy, a chyba zauważyłeś, że podane zostały wybiórczo kolumny i całość jest bardziej rozbudowana. To także ma wpływ na szybkość skryptów naszych. To, że w zależności czy jest to Firebird, Oracle, Mysql, MSSQL czy Postgress czasy mogą być różne, jest dla mnie równie oczywiste. Zarówno jednak newsów jak i userów z każdym dniem przybywa. Nowa baza jest szybka, ale niech się zacznie zapełniać i stronę zacznie odwiedzać coraz więcej userów to wtedy takie drobiazgi mają wpływ i bez optymalizacji oraz cache'owania wyników najczęstszych zapytań daleko nie pociągnie się. Albo raczej zajedzie bazę ilością nadmiarowych operacji. Wiem, że wspomniana przez Ciebie jest szybsza w działaniu niż MySQL, ale też nie wszędzie jest ona dostępna. Dla faktycznych testów należałoby oba zapytania puścić w tych samych warunkach dla różnych stopni zapełnienia bazy danymi i dla różnych rodzajów baz. Ja pracuję w firmie, gdzie mam pod sobą kilka serwisów mających dziennie kilkadziesiąt tysięcy odsłon i około 2k real users według google analytics, czyli tych co nie blokują ich skryptów. Optymalizacja na takich ma znaczenie i dlatego staram się mieć jak najbardziej optymalne rozwiązania. Jeśli pracujesz na takich lub większych serwisach to zapewne mnie rozumiesz. Nie zaczynajmy więc niepotrzebnie flame'a i nie zaśmiecajmy niepotrzebną wojną tematu.
Moglibyśmy przecież się spierać czy gdy wiadomości jest X, userów w bazie Y, a odwiedzających jednocześnie Z to od pewnego momentu któreś z naszych rozwiązań może być szybsze o ileś od drugiego. Ja staram nie odrywać jednego zapytania od kontekstu działania całości serwera bo jest różnica w serwerze na localhoście i publicznym, do którego ma dostęp więcej niż jedna osoba i także masz tego świadomość podobnie jak ja. Dopiero po postawieniu serwisu w necie wychodzi jego optymalizacja, gdy do bazy jest jednocześnie wiele zapytań. Tutaj już różnica kilkudziesięciu czy kilkuset milisekund przy często wywoływanych funkcjach zaczyna grać rolę. Ale to już bardziej do tematu lub działu o optymalizacji powinno by było zostać przeniesione. Nie uważasz? Za dużo czynników ma wpływ ale przy jednakowym obciążeniu początkowa niewielka różnica zaczyna się powiększać. I stąd każdy niepotrzebny JOIN, każdy niepotrzebny SELECT to dodatkowy narzut czasowy, którego można uniknąć przebudowując zapytanie. I tylko o to mi chodzi. Nie ma co kruszyć kopii gdy nie jest to potrzebne. Ja testy swoich zapytań i skryptów mam codziennie idąc do pracy. Mam to szczęście, że pracuję w zawodzie wyuczonym i mam z tym kontakt przynajmniej 8 godzin dziennie jako praca, a i nieraz jeszcze po niej - hobbystycznie.

Ten post edytował thek 23.08.2009, 16:36:13
Go to the top of the page
+Quote Post

Posty w temacie


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

 



RSS Aktualny czas: 11.10.2025 - 17:35