Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP] Tagi - struktura bazy danych i pobieranie kilku wartości
Forum PHP.pl > Forum > Przedszkole
arek33
Witam ponownie,
Przeczesałem wczoraj połowę internetu, ale problem nadal jest na podobnym poziomie na jakim był przed rozpoczęciem poszukiwań. Sprawa dotyczy się systemu dodawania newsów i słów kluczowych (tagów).

Struktura bazy wyglądać będzie następująco(?):

news:
- id_news
- tytul
- tresc
- data
- autor
- id_tags (?)

tagi:
- id_tags
- tag

tagi_news
- id_tags (int?)
- id_news

Proszę o kompetentną osobę czy powyższa struktura jest prawidłowa czy może warto coś dodać/zmienić?

Przykład wyświetlania artykułu (news):
Tytuł: Nowy wpis
Treść: Lorem ipsum...
Data: Dzisiaj o 19:11
Autor: Admin
Tagi: nowy wpis, lorem ipsum, lorem

Jak widać w powyższym przykładzie chcę użyć 3+ słów kluczowych, niemniej jednak nie wiem jak się za to zabrać.

Ad1. Przede wszystkim zależy mi na opinii czy struktura bazy danych jest odpowiednia?
Ad2. Mając przypisane:

id_tags = 1
tag = nowy wpis

id_tags = 2
tag = lorem ipsum

id_tags = 3
tag = lorem

Jak wpisać wszystkie 3 do id_tags z tabeli news? Rozumiem, że relacja zachodząca pomiędzy tabelami to jeden do wielu, niemniej jednak nadal nie mam odpowiednich wskazówek do satysfakcjonującego mnie rozwiązania. Z góry dziękuję za pomoc, linki do artykułów, które będą mi w stanie pomóc oraz pozostałe cenne wskazówki.

Arek
dziamber
Ja bym zrobił to tak:

  1. news:
  2. - id_news
  3. - tytul
  4. - tresc
  5. - DATA
  6. - autor
  7. - tags


  1. tags:
  2. - id
  3. - nazwa


I np. jak masz trzy tagi w newsie to trzymasz ich id oddzielone przecinkami, a jak chcesz je wyciągnąć to coś w stylu:

  1. # pobierasz dane z bazy
  2. $tagi = $dane_z_bazy->tags;
  3. $tagi = explode(",", $tagi);
  4. $ile_tagow = count($tagi);
  5. $jest = 0;
  6. while($jest <= $ile_tagow) {
  7. echo $tagi[$jest];
  8. $jest++;
  9. }
Bags_Bunny
Orl korrect! Mam podobną sytuację z użytkownikami w Kohanie. Jest tabela user z danymi użytkowników (u Ciebie nowości), tabela z rolami tychże (odpowiednik Twoich tagów) oraz tabela z przypisaniami zwana role_user, czyli odpowiednik Twojego tagi_news.

Załóżmy, iż chcę wybrać id użytkownika, jego pierwsze imię, a także jego role w postaci id_roli:nazwa_roli;id_roli:nazwa_roli;...
Co więcej, chcę aby ta lista była posortowana w/g nazwy roli, a całość wyników w/g imienia.

Mogę to zrobić na przykład następującym zapytaniem:
  1. SELECT u.user_id, u.first_name, GROUP_CONCAT( DISTINCT CONCAT(r.role_id, ":", r.name) ORDER BY r.name ASC SEPARATOR ";" ) roles FROM user u NATURAL JOIN role_user ru NATURAL JOIN role r GROUP BY user_id ORDER BY u.first_name

Dla jasności dodałem wszędzie nazwę tabeli.

--edit--
Dla ułatwienia wrzucam jeszcze strukturę:
  1. --
  2. -- Table structure for table `role`
  3. --
  4.  
  5. CREATE TABLE `role` (
  6. `role_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  7. `name` varchar(32) NOT NULL,
  8. `description` varchar(255) NOT NULL,
  9. PRIMARY KEY (`role_id`),
  10. UNIQUE KEY `uniq_name` (`name`)
  11. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=3 ;
  12.  
  13. -- --------------------------------------------------------
  14.  
  15. --
  16. -- Table structure for table `role_user`
  17. --
  18.  
  19. CREATE TABLE `role_user` (
  20. `user_id` int(10) UNSIGNED NOT NULL,
  21. `role_id` int(10) UNSIGNED NOT NULL,
  22. PRIMARY KEY (`user_id`,`role_id`)
  23. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  24.  
  25. -- --------------------------------------------------------
  26.  
  27. --
  28. -- Table structure for table `user`
  29. --
  30.  
  31. CREATE TABLE `user` (
  32. `user_id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  33. `created_at` int(16) UNSIGNED NOT NULL,
  34. `updated_at` int(16) UNSIGNED DEFAULT NULL,
  35. `password` varchar(64) NOT NULL,
  36. `first_name` varchar(16) NOT NULL,
  37. `email` varchar(64) NOT NULL,
  38. `logins` int(10) UNSIGNED NOT NULL DEFAULT '0',
  39. `last_login` int(10) UNSIGNED DEFAULT NULL,
  40. `deleted` int(1) UNSIGNED NOT NULL DEFAULT '0',
  41. PRIMARY KEY (`user_id`),
  42. UNIQUE KEY `email_UNIQUE` (`email`)
  43. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=13 ;


--edit--
Jeszcze drobne uwagi kosmetyczne:
Weź pod uwagę, że DISTINCT jest akurat w tym przypadku zbędny, bo wszystko ma klucze. Napisałem z rozpędu wink.gif.
Ponadto, u Ciebie zapewne LEFT JOIN sprawdzi się bardziej niż NATURAL JOIN, który użyłem tutaj dla przejrzystości zapytania.
arek33
Dzięki Panowie za pomoc! Rozwiązałem to nieco inaczej, ale te dwie riposty nakierowały mnie odpowiednio - jestem zadowolony z rezultatu. Ostatnie chyba pytanie mam - jaką funkcją w PHP dobiorę się do ostatniego wyniku pobranego z bazy danych za pośrednictwem pętli while? Wyrzucam moje tagi: 123, abc, zxc, cxz, itp.

  1. echo "".$r['id_newsa'].", ";


I jak wiadomo wynik mój będzie wyglądał następująco: tag1, tag2, tag3, [przecinek na końcu], w jaki sposób mogę się go pozbyć?

Cytat(arek33 @ 18.04.2011, 00:15:49 ) *
Dzięki Panowie za pomoc! Rozwiązałem to nieco inaczej, ale te dwie riposty nakierowały mnie odpowiednio - jestem zadowolony z rezultatu. Ostatnie chyba pytanie mam - jaką funkcją w PHP dobiorę się do ostatniego wyniku pobranego z bazy danych za pośrednictwem pętli while? Wyrzucam moje tagi: 123, abc, zxc, cxz, itp.

  1. echo "".$r['id_newsa'].", ";


I jak wiadomo wynik mój będzie wyglądał następująco: tag1, tag2, tag3, [przecinek na końcu], w jaki sposób mogę się go pozbyć?

Gdyby kogoś to interesowało to rozwiązałem to w następujący sposób:

  1. if($mnr <= $r['id_newsa']){
  2.  
  3. echo "".$r['id_newsa']."";
  4. }
  5. else{
  6.  
  7. echo "".$r['id_newsa'].", ";
  8.  
  9. }
  10. // gdzie $mnr = mysql_num_rows($wynik)
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.