Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL]Tagi dla bloga
Forum PHP.pl > Forum > Przedszkole
maviozo
Nie szukam tu gotowca, generalnie jakoś sobie radzę. Rozważania są raczej teoretyczne, niż praktyczne. Otóż wynajduję koło na nowo i zastanawiam się, jak lepiej ugryźć temat tagowania bloga smile.gif
Bazowo mamy dwie tabele - blog i tagi. Wiadomo, w tagach mamy id_taga i nazwę, ewentualnie jakieś tam inne zmienne. Naturalnie zakładamy, że do każdego bloga można przypisać różną ilość tagów.

Rozważam w sumie dwie opcje, łatwiejsza i trudniejsza wink.gif

Pierwsza z nich to po prostu dodanie dodatkowego pola do tablicy głównej z blogiem (np. tagi) i podanie tagów po spacji, czy przecinku, potem problem z wyszukaniem po tagu załatwiać warunkiem "tagi zawiera", przy generowaniu rozbijać to przez PHP itp.
Druga z nich to dodanie trzeciej tabeli blog_tagi ze strukturą: id_powiazania, blog, tag. Potem każde pojedyncze powiązanie polega na podaniu id bloga i id tagu.

Czyli np. jeżeli uznam, że dany wpis ma mieć 5 tagów, to przy pierwszym wariancie w polu będzie: "1 2 4 5 8", a przy drugim wariancie będzie to 5 wierszy w tabeli.

Blog nie będzie pewnie bardzo poczytny, więc problemy wydajności nie grają wielkiej roli a rozważania biorą się raczej z chęci rozwoju, blablabla smile.gif mimo wszystko lubię robić coś porządnie i stąd pytanie. Wersja druga wydaje mi się właśnie taką bardziej porządną smile.gif
nospor
Tak, jedyna sluszna to wersja 2
maviozo
Ok. Jakoś to sobie ogarnąłem od strony backendu.

Mam jednak pewien, nazwijmy to problem z frontendem.

Czy da się jednym zapytaniem pobrać z tabeli blog tytuł, treść a także w jakiś sposób pobrać wszystkie powiązane z nim tagi? Pewnie trzeba użyć podzapytania, ale czy da się w ten sposób zwrócić pionową tabelę w jednej kolumnie głównego zapytania?

Dla jednego, wyświetlanego artykułu to nie jest problem, zrobić dwa zapytania a nie jedno i przeparsować listę przypisanych tagów przez PHP dla ładnego kodu z linkami do danego tagu. Ale przy liście artykułów, którą dostaję z jednego zapytania, gdybym chciał dostać dla każdego z nich listę przypisanych tagów, liczba zapytań katastrofalnie rośnie. jest więc pewnie jakiś myk, na połączenie tabel.

Podpowiedź?
nospor
zwykly LEFT JOIN na tabele z tagami a nie zadne podzapytanie
maviozo
Przepraszam, pewnie to głupie pytanie, ale jakoś sobie tego nie mogę wyobrazić. Jeden blog = jeden wiersz w tabeli z blogiem. Natomiast zestaw tagów dla jednego bloga to tyle wierszy ile tagów.
Przecież tabela, w której wylistowane są powiązania tagów, dla jednego bloga ma kilka wierszy - chyba że to ma tak zadziałać.
Tylko tyle, że wtedy jeśli jeden blog ma 4 tagi, dostanę 4 zdublowane wiersze - to ma tak działać? Jest to jakieś wyjście, ale wtedy muszę przez PHP odfiltrować duble.
bostaf
Cytat(maviozo @ 14.11.2013, 14:27:13 ) *
Wersja druga wydaje mi się właśnie taką bardziej porządną smile.gif

Zdecydowanie tak. Uzasadnienie: normalizacja bazy danych + prędkość kilka rzędów większa niż w przypadku rozwiązania 1.

Cytat(maviozo @ 31.12.2013, 00:58:23 ) *
Przepraszam, pewnie to głupie pytanie, ale jakoś sobie tego nie mogę wyobrazić. Jeden blog = jeden wiersz w tabeli z blogiem. Natomiast zestaw tagów dla jednego bloga to tyle wierszy ile tagów.
Przecież tabela, w której wylistowane są powiązania tagów, dla jednego bloga ma kilka wierszy - chyba że to ma tak zadziałać.
Tylko tyle, że wtedy jeśli jeden blog ma 4 tagi, dostanę 4 zdublowane wiersze - to ma tak działać? Jest to jakieś wyjście, ale wtedy muszę przez PHP odfiltrować duble.

Zależy jaki efekt i dane chcesz uzyskać. Jeśli tylko nazwy tagów to dobrą metodą jest zgrupowanie wyniku klauzulą GROUP BY i wykorzystanie funkcji agregującej GROUP_CONCAT:
  1. SELECT
  2. b.id_bloga,
  3. b.tytul_bloga,
  4. GROUP_CONCAT(t.nazwa_tagu SEPARATOR ',') AS tagi
  5. FROM blogi b
  6. LEFT JOIN blogi_tagi bt ON bt.id_bloga = b.id_bloga
  7. LEFT JOIN tagi t ON t.id_tagu = bt.id_tagu
  8. GROUP BY b.id_bloga
...a następnie rozbijanie wartości z kolumny "tagi" w PHP, z explode().

Tak jak Ty kombinujesz też jest dobrze (może nawet lepiej), bo masz możliwość uzyskania pełnego zestawu informacji o tagach (identyfikatora, nazwy, komentarza, itd) i wykorzystania tego w widoku np. do skomponowania ładnego linku (z komentarzem w tooltipie) do listy blogów z danym tagiem. Odfiltrowanie wielokrotnych wartości to też żaden problem bo w jednym przejściu po wyniku zapytania to zrobisz.

Metoda zależy od zamierzonej funkcjonalności.
nospor
Cytat
Tylko tyle, że wtedy jeśli jeden blog ma 4 tagi, dostanę 4 zdublowane wiersze - to ma tak działać? Jest to jakieś wyjście, ale wtedy muszę przez PHP odfiltrować duble.

http://nospor.pl/grupowanie-wynikow.html
baambaam
Ja bym to zrobił jeszcze inaczej, zamiast jednej tabli dodaj dwie
1. blog_tagi ze strukturą: id_tagu, tag.
2. tagi_relacja struktura: id_tagu, id_artykułu.
nospor
bambam a niby o czym my tu przez caly czas mowimy?
baambaam
Cytat(maviozo @ 14.11.2013, 14:27:13 ) *
Druga z nich to dodanie trzeciej tabeli blog_tagi ze strukturą: id_powiazania, blog, tag. Potem każde pojedyncze powiązanie polega na podaniu id bloga i id tagu.

Czyli np. jeżeli uznam, że dany wpis ma mieć 5 tagów, to przy pierwszym wariancie w polu będzie: "1 2 4 5 8", a przy drugim wariancie będzie to 5 wierszy w tabeli.

nie potrzebuje trzech kolumnw tabeli blog_tagi
przy drugiej wersji ma 5 wierszy w relacjach i 5 w blog_tagi
widze, że wy rozumiecie (po zapytaniu), tylko nie wiem czy autor załapał
maviozo
Faktycznie trzecia kolumna nie jest jakoś szczególnie potrzebna, w sumie to taki nawyk, że zawsze robię kolumnę z unikalnym ID - którejś mądrej książce o mysql tak zalecali :]
Zabieram się za lekturę podanych linków i sposobów.

Post bostafa idealnie się sprawdził. Dzięki wielkie. Nie znałem tej bardzo przydatnej funkcji.


Co do porady nospora to faktycznie zwykłe dołączenie tabeli z powiązaniami wystarczy, żeby mieć listę tagów ze zdublowanymi danymi. Skorzystam jednak od razu z grupowania zaproponowanego przez bostafa smile.gif

Dzięki za pomoc. Można zamknąć.
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.