Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

> Pytanie do zapytania
quizer
post
Post #1





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 20.06.2010

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


Witam, mam następujące zapytanie:

  1. SELECT artykuly.id, artykuly.tytul, artykuly.krotki, artykuly.DATA, artykuly.img, uzytkownicy.nick, kategorie.opis FROM artykuly INNER JOIN uzytkownicy ON artykuly.uzytkownik = uzytkownicy.id INNER JOIN kategorie ON artykuly.typ = kategorie.id INNER JOIN komentarze ON artykuly.id = komentarze.artykul ORDER BY DATA DESC LIMIT 0, 10


Chciałbym dodać do tabeli wyjściowej jeszcze jedną kolumnę w której będą policzone komentarze dla danego artykułu (count(komentarze.id)). Nie bardzo wiem jak się za to zabrać by dla każdego artykułu był podliczone tylko jego komentarze. Dla pojedyńczego artykułu takie zapytanie wyglądałoby tak:

  1. SELECT count(komentarze.id), artykuly.id, artykuly.tytul, artykuly.krotki, artykuly.DATA, artykuly.img, uzytkownicy.nick, kategorie.opis FROM artykuly INNER JOIN uzytkownicy ON artykuly.uzytkownik = uzytkownicy.id INNER JOIN kategorie ON artykuly.typ = kategorie.id INNER JOIN komentarze ON artykuly.id = komentarze.artykul WHERE komentarze.artykul = 3 ORDER BY DATA DESC LIMIT 0, 10


Pozdrawiam


--------------------
Go to the top of the page
+Quote Post
 
Start new topic
Odpowiedzi (1 - 12)
Mchl
post
Post #2





Grupa: Zarejestrowani
Postów: 855
Pomógł: 145
Dołączył: 17.07.2008
Skąd: High Memory Area

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


Kod
SELECT
  artykuly.id, artykuly.tytul, artykuly.krotki, artykuly.DATA, artykuly.img, uzytkownicy.nick, kategorie.opis
FROM
  artykuly
INNER JOIN
  uzytkownicy ON artykuly.uzytkownik = uzytkownicy.id
INNER JOIN
  kategorie ON artykuly.typ = kategorie.id
INNER JOIN (
  SELECT artykul, COUNT(*) FROM komentarze GROUP BY artykul
) AS komentarze ON artykuly.id = komentarze.artykul
ORDER BY DATA DESC
LIMIT 0, 10


Ten post edytował Mchl 26.06.2010, 20:32:04
Go to the top of the page
+Quote Post
quizer
post
Post #3





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 20.06.2010

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


Dzieki, tego potrzebowałem ;)


--------------------
Go to the top of the page
+Quote Post
Crozin
post
Post #4





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Zliczanie każdorazowo ilości komentarzy to zły pomysł. Rozwiązuje się to poprzez dodatkową kolumnę "ilość komentarzy" w tabeli, której rekordy są komentowane (tutaj: artykuły). Dzięki temu nie musisz katować bazy bazy niepotrzebnym podzapytaniem, które może w znaczący sposób obciążyć bazę.

Inkrementacja/dekrementacja wartości "ilość komentarzy" przy dodawania/usuwaniu komentarza jest jest jakimś problemem.
Go to the top of the page
+Quote Post
thek
post
Post #5





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




OT: chyba jest ta inkrementacja/dekrementacja problemem... Skrypt na tym forum też tego nie obsługuje winksmiley.jpg Poza tym podpisuję się pod Twoim zdaniem Crozin. Każdorazowe liczenie to ubijanie bazy. Lepiej to wyrzucić jako osobne pole, które odpowiednio in-/dekrementujemy w określonych przypadkach.


--------------------
Najpierw był manual... Jeśli tam nie zawarto słów mądrości to zapytaj wszechwiedzącego Google zadając mu własciwe pytania. A jeśli i on milczy to Twój problem nie istnieje :D
Go to the top of the page
+Quote Post
quizer
post
Post #6





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 20.06.2010

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


Cytat(Crozin @ 26.06.2010, 22:15:49 ) *
Zliczanie każdorazowo ilości komentarzy to zły pomysł. Rozwiązuje się to poprzez dodatkową kolumnę "ilość komentarzy" w tabeli, której rekordy są komentowane (tutaj: artykuły). Dzięki temu nie musisz katować bazy bazy niepotrzebnym podzapytaniem, które może w znaczący sposób obciążyć bazę.

Inkrementacja/dekrementacja wartości "ilość komentarzy" przy dodawania/usuwaniu komentarza jest jest jakimś problemem.


Dzięki za podpowiedź. Postaram się zastosować. Czyli wtedy przy dodawaniu/usuwaniu komentarza trzeba wysłać dwa zapytania do bazy - nowy rekord dla komentarzy i edycja rekordu dla artykułów? I dlaczego inkrementacja/dekrementacja stanowi problem?


--------------------
Go to the top of the page
+Quote Post
Crozin
post
Post #7





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Cytat
I dlaczego inkrementacja/dekrementacja stanowi problem?
Oczywiście chodziło mi o to, że nie stanowi problemu. winksmiley.jpg
Go to the top of the page
+Quote Post
Mchl
post
Post #8





Grupa: Zarejestrowani
Postów: 855
Pomógł: 145
Dołączył: 17.07.2008
Skąd: High Memory Area

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


Cytat(quizer @ 28.06.2010, 11:06:10 ) *
Dzięki za podpowiedź. Postaram się zastosować. Czyli wtedy przy dodawaniu/usuwaniu komentarza trzeba wysłać dwa zapytania do bazy - nowy rekord dla komentarzy i edycja rekordu dla artykułów? I dlaczego inkrementacja/dekrementacja stanowi problem?


Dwa zapytania, najlepiej w transakcji. Ewentualnie triggery.
Go to the top of the page
+Quote Post
quizer
post
Post #9





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 20.06.2010

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


Cytat(Crozin @ 28.06.2010, 11:22:09 ) *
Oczywiście chodziło mi o to, że nie stanowi problemu. ;)


Ok, rozumiem ;)


Cytat(Mchl @ 28.06.2010, 11:35:08 ) *
Dwa zapytania, najlepiej w transakcji. Ewentualnie triggery.


Transakcja czyli po prostu:

  1. $db->autocommit(FALSE);
  2. $db->query("INSERT INTO komentarze [...]");
  3. $db->query("UPDATE artykuly SET ile_komentarzy = ile_komentarzy+1 [...]");
  4. $db->commit();


Aye?

Ten post edytował quizer 28.06.2010, 16:14:10


--------------------
Go to the top of the page
+Quote Post
Mchl
post
Post #10





Grupa: Zarejestrowani
Postów: 855
Pomógł: 145
Dołączył: 17.07.2008
Skąd: High Memory Area

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


Nie zapomnij o rollbacku winksmiley.jpg

  1. $db->autocommit(FALSE);
  2. $result = $db->query("INSERT INTO komentarze [...]");
  3. if(!$result || !$db->query("UPDATE artykuly SET ile_komentarzy = ile_komentarzy+1 [...]")) {
  4. $db->rollback();
  5. } else {
  6. $db->commit();
  7. }


Ten post edytował Mchl 28.06.2010, 17:35:48
Go to the top of the page
+Quote Post
quizer
post
Post #11





Grupa: Zarejestrowani
Postów: 14
Pomógł: 0
Dołączył: 20.06.2010

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


Dzięki,
mam jeszcze jedno pytanie podobnego sortu. Do wspomnianych artykułów prócz komentarzy chcę dać możliwość oceniania przez użytkowników. I tutaj się pojawia pytanie gdzie te oceny umieszczać by było to najbardziej optymalne. a) w oddzielnej tabeli z ocenami (uzytkownik, artykul, ocena) B) kolumna w tabeli artykuly z ocenami (uzytkownik:ocena;uzytkownik:ocena;), c) w tabeli z użytkownikami (artykul:ocena;artykul:ocena)? Z poprzednich postów wnioskuje też, że nie ma co pobierać AVG z ocen tylko lepiej po prostu dodać kolumnę 'średnia ocen' do tabeli z artykułami?

Ten post edytował quizer 6.07.2010, 12:54:12


--------------------
Go to the top of the page
+Quote Post
Mchl
post
Post #12





Grupa: Zarejestrowani
Postów: 855
Pomógł: 145
Dołączył: 17.07.2008
Skąd: High Memory Area

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


B i C łamie zasady normalizacji. Co nam zostaje?

Czy lepiej liczyć za każdym razem, czy trzymać w dodatkowej kolumnie i odświeżać, czy cachować w tabeli MEMORY albo w inny sposób, to wszystko zależy od tego jak bardzo ta operacja obciąży Ci bazę.

Masz do rozważenia dwa czynniki:
1. Jak często zmieniają się dane do liczenia średniej
2. Jak często potrzebna Ci jest średnia

Jeżeli ta średnia potrzebna Ci jest sporadycznie, to nie ma co sobie bazy zaśmiecać dodatkowymi konstruktami, lepiej ją policzyć.
Jeżeli średnia potrzebna Ci jest często, a dane do liczenia zmieniają się stosunkowo żadko, wygodnie jest zrobić sobie dadatkową kolumnę z wynikiem.
Jeżeli średnia potrzebna jest często a dane do liczenia zmieniają się równie często, warto zastanowić się nad jakimś mechanizmem cache'ującym gdzie średnia będzie odświeżana np raz na minutę.
Go to the top of the page
+Quote Post
Crozin
post
Post #13





Grupa: Zarejestrowani
Postów: 6 476
Pomógł: 1306
Dołączył: 6.08.2006
Skąd: Kraków

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


Najprawdopodobniej najlepszym rozwiązaniem będzie tutaj hybryda, tj. dodatkowa tabela z głosami (jako podstawa) plus kolumna "ocena" w ocenianym elemencie. Po dodaniu głosu dodajesz nowy rekord do tabeli na głosy (id użytkownika, id ocenianego elementu, data dodania, ip, ocena i co tam jeszcze potrzebujesz) oraz uaktualniasz średnią ocen (czy tam średnią i ilość głosów).

Po co więc dodatkowa tabela, z której się praktycznie nie korzysta? Bo zawiera ona szczegółowe dane przydatne przy generowaniu statystyk, sprawdzaniu czy dany użytkownik już głosował itp. itd.
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 Aktualny czas: 21.08.2025 - 17:18