Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: system newsów - kategorie
Forum PHP.pl > Forum > PHP
xxdrago
Witam, ja się chciałem zapytać czy to jest dobry pomysł z kategoriami newsów najpierw dam tabele:

Nazwy kategorii, id , typ
  1. CREATE TABLE `kategorie` (
  2. `kategoria_id` int(11) NOT NULL AUTO_INCREMENT,
  3. `kategoria_nazwa` text collate utf8_polish_ci NOT NULL,
  4. `typ` int(11) NOT NULL DEFAULT '0',
  5. KEY `kategoria_id` (`kategoria_id`)
  6. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=3 ;




W tej tabeli mam newsy:


  1. CREATE TABLE `newsy_strony` (
  2. `id` smallint(6) NOT NULL AUTO_INCREMENT,
  3. `nazwa` text collate utf8_polish_ci NOT NULL,
  4. `data` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
  5. `autor` varchar(255) collate utf8_polish_ci NOT NULL DEFAULT '',
  6. `tresc` text collate utf8_polish_ci NOT NULL,
  7. `typ` text collate utf8_polish_ci NOT NULL,
  8. `kategoria_id` int(11) NOT NULL,
  9. `link` text collate utf8_polish_ci NOT NULL,
  10. PRIMARY KEY (`id`)
  11. ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=127 ;


`kategoria_id` int(11) NOT NULL, - id kategorii.

Myślałem sobie zrobić tak żeby była możliwość, kilku kategorii dla jednego newsa, więc zastosowałbym funkcje explode.

A przykładowy rekord z kategoria_id wyglądałby tak:
Kod
5,7,3


Potem funkcją
  1. explode(','$rekord['kategoria_id'])
bym to ładnie podzielił do tabeli, następnie wyszukałbym w bazie nazwy kategorii, po id. Czy to jest doby pomysł?
Adi32
Łamiesz tym zasadę atomowości.
Powinieneś tutaj zastosować relację wiele do wielu (czyli zrobić tabelę pośrednią "id_news,id_kategoria").
Crozin
OT: @Adi32: http://en.wikipedia.org/wiki/Atomicity_(database_systems)
xxdrago
Zrobiłem tak jak mówicie, zrobiłem sobie tabele:

Co tutaj można by było z optymalizować?

  1. if (is_null($news)) {
  2. $dane = 'SELECT * FROM `newsy_strony` WHERE typ =1 ORDER BY `data` DESC limit ' . $start . ',' . ($end - $start + 1);
  3. $sql = $db->query($dane);
  4.  
  5.  
  6. while ($newss = $sql->fetch_assoc()) {
  7. $bb = new BbCode(); // Dodanie BB-CODE
  8. $bb->parse($newss['tresc']); // Prasowanie
  9. $length = 500; // Sktracanie tekstu...
  10. $cutText = $bb->cutText($length);
  11.  
  12. // Ilosc komentarzy
  13. $sql_ilosc = 'SELECT COUNT( * ) FROM komentarze WHERE id =' . $newss['id'];
  14. $sql_iloscc = $db->query($sql_ilosc);
  15. $newse = $sql_iloscc->fetch_assoc();
  16.  
  17. // Kategoria
  18. $kategoria_sql = 'SELECT * FROM `kategorie_newsy` where news_id=' . $newss['id'];
  19. $kategoria = $db->query($kategoria_sql);
  20. $kategoriaa = $kategoria->fetch_assoc();
  21.  
  22. if (empty($kategoriaa['kategoria_id']))
  23. {
  24. $id_k =1;
  25. }
  26. else
  27. {
  28. $id_k = $kategoriaa['kategoria_id'];
  29. }
  30.  
  31. // Zap2
  32. $kategoria2_sql = 'SELECT * FROM `kategorie` where kategoria_id=' . $id_k;
  33. $kategoria2 = $db->query($kategoria2_sql);
  34. $kategoriaa2 = $kategoria2->fetch_assoc();
  35.  
  36.  
  37.  
  38. // To poniżej dodajemy co cache
  39.  
  40. $news[] = array(
  41. 'nazwa' => znaki('znaki', $newss['nazwa']),
  42. 'id' => $newss['id'],
  43. 'link' => $newss['link'],
  44. 'tresc' => $cutText,
  45. 'autor' => $newss['autor'],
  46. 'data' => $newss['data'],
  47. 'komentarze' => $newse['COUNT( * )'],
  48. 'kategoria' => $kategoriaa2['kategoria_nazwa'],
  49. );
  50. }
  51. $cache->Put('news' . $actualPage, $news, '@queries');
  52. }
wujek2009
Nie wyświetlaj od razu newsów tylko zapisz je wszystkie do tablicy najpierw.
Czyli przerób pętle z #6 linijki na mniej więcej taki zarys;
  1. $newsy = $id_newsow = array();
  2.  
  3. while ($newss = $sql->fetch_assoc()) {
  4. $newsy[] = $newss;
  5. $id_newsow[] = $newss['news_id']; // przekaż id newsa
  6. }


Po co? Bo wyświetlając 15 newsów na stronę powielasz 15x zapytanie z linijki 18 a można to zrobić mniej więcej tak:

  1.  
  2. $newsy = $id_newsow = array();
  3.  
  4. while ($newss = $sql->fetch_assoc()) {
  5. $newsy[] = $newss;
  6. $id_newsow[] = $newss['news_id']; // przekaż id newsa
  7. }
  8.  
  9. if ( sizeof($newsy) )
  10. {
  11. // sa newsy
  12.  
  13.  
  14. // dla $id_newsow możesz zastosować też array_unique aby usunęło z tablicy te same ID do pobrnaia
  15. // bo po co ma pobierać 3x kategorie o ID = 19?
  16. $pobierzKategorie = "select * from bla bla where ID_KATEGORI IN(". implode(',', $id_newsow) .")";
  17. // i teraz
  18. $kategorie_row = array();
  19.  
  20. foreach ( $pobierzKategorie as $k => $v )
  21. $kategorie_row[$v['id_kategori']] = $v;
  22.  
  23. // wyświetlamy teraz newsy:
  24.  
  25. foreach ( $newsy as $k => $v )
  26. {
  27. $tytul_newsa = $v['title']; // taki przykład;
  28. $nazwa_kategori = isset($kategorie_row[$v['id_kategori']]) ? $kategorie_row[$v['id_kategori']]['nazwa'] : NULL;
  29.  
  30. echo 'tytuł: '. $tytul_newsa .' jest w kategori: '. $nazwa_kategori;
  31. }
  32.  
  33. }
  34. else
  35. die('nie ma newsów');


co można jeszcze zoptymalizować? zapytanie z #13 linjki.
otwórz w tabeli newsów kolumnę "liczba_komentarzy" i gdy ktoś doda nowy komentarz to rób zwykłe UPDATE +1 (aby liczba się zwiększała); oczywiście przy usuwaniu komentarzy to -1 :-)

i wtedy te zapytanie z #13 kompletnie to wyrzucenia.

// pisałem z palca, nie analizowałem kolumn z Twojej bazy.
xxdrago
Wiesz co, patrz całość wygląda tak:

  1. <?php
  2.  
  3. # --- Dodajemy naglowki --- #
  4. ob_start(); // Buforowanie
  5. error_reporting(E_ALL); // Raportowanie bledow
  6. session_start(); // Sesja
  7. # --- Odpalamy odpowienie pliki --- #
  8. require('includes/BbCode.php'); // BB-CODE
  9. require('includes/function.php'); // Funkcje
  10. require('includes/template.php'); // Klasa szablonow
  11. require('config.php'); // Plik konfiguracyjny
  12. require('includes/Pager.class.php'); // Pager
  13. require('includes/Cache.class.php');
  14. require('includes/CacheFileDriver.class.php');
  15. # --- Klasy --- #
  16. $bb = new BbCode(); // BB-CODE
  17. $tpl = new Template($sciezka_styl); // Szablon
  18. $db = lacz(); // Baza danych MYSQL
  19. $cache = new Cache();
  20. $ile_komentarzy = new ile_komentarzy();
  21.  
  22. /*
  23.  
  24. SELECT newsy_strony.id,newsy_strony.nazwa,newsy_strony.data,newsy_strony.autor,newsy_st
    rony.tresc,newsy_strony.typ,newsy_strony.link, COUNT( komentarze.id ) ilosc
  25. FROM newsy_strony
  26. LEFT JOIN komentarze ON komentarze.id = newsy_strony.id
  27. GROUP BY newsy_strony.id
  28.  
  29. */
  30. $cache->AddDriver('fileDriver', new CacheFileDriver('Cache'));
  31.  
  32. $cache->AddGroup('@queries', array('lifetime' => 300, 'driver' => 'fileDriver', 'hashid' => true));
  33. # --- Konfiguracja Templeate ---#
  34. $nazwa_plikuu = 'index';
  35. $rozszezeniee = '.html'; // Rozszezenie HTML/TPL
  36. $nazwa_Podstrony = 'Strona Główna';
  37. $nastronie = 5;
  38. # --- Skrypt --- #
  39. $tpl->load_file($nazwa_plikuu . $rozszezeniee, $nazwa_plikuu); // Ladujemy plik
  40. //Obiekt nalezy do grupy queries
  41. // --- Cache PAGER
  42.  
  43. $pager = $cache->Get('pager', '@queries');
  44. if (is_null($pager)) {
  45. $sql_pager = $db->query('SELECT count( * ) FROM newsy_strony where typ=1');
  46. $row = $sql_pager->fetch_array();
  47. $pager = array();
  48. $pager['ilosc_rekordow'] = $row['0'];
  49.  
  50. $cache->Put('pager', $pager, '@queries');
  51. }
  52. // $pager['ilosc_rekordow']; - Zwraaca ilosc rekordow
  53. // --- Cache pager
  54.  
  55. if (komentarze_on_off() == true) {
  56. $komentarze = 1;
  57. } else {
  58. $komentarze = 0;
  59. }
  60. $pagers = new Pager('id');
  61. $pagers->SetTotalRecords($pager['ilosc_rekordow']);
  62. $pagers->SetRecordsPerPage($nastronie);
  63. $pagers->SetPagesPerNav(3);
  64. $pagers->Make(true);
  65. $pag = $pagers->Render();
  66. $actualPage = $pagers->GetActualPage(); //tu aktualna strona
  67. $start = $pagers->GetIndexRecordStart();
  68. $end = $pagers->GetIndexRecordEnd();
  69.  
  70.  
  71. $news = $cache->Get('news' . $actualPage, '@queries');
  72.  
  73. if (is_null($news)) {
  74. $dane = 'SELECT * FROM `newsy_strony` WHERE typ =1 ORDER BY `data` DESC limit ' . $start . ',' . ($end - $start + 1);
  75. $sql = $db->query($dane);
  76.  
  77.  
  78. while ($newss = $sql->fetch_assoc()) {
  79. $bb = new BbCode(); // Dodanie BB-CODE
  80. $bb->parse($newss['tresc']); // Prasowanie
  81. $length = 500; // Sktracanie tekstu...
  82. $cutText = $bb->cutText($length);
  83.  
  84. // Ilosc komentarzy
  85. $sql_ilosc = 'SELECT COUNT( * ) FROM komentarze WHERE id =' . $newss['id'];
  86. $sql_iloscc = $db->query($sql_ilosc);
  87. $newse = $sql_iloscc->fetch_assoc();
  88.  
  89. // Kategoria
  90. $kategoria_sql = 'SELECT * FROM `kategorie_newsy` where news_id=' . $newss['id'];
  91. $kategoria = $db->query($kategoria_sql);
  92. $kategoriaa = $kategoria->fetch_assoc();
  93.  
  94. if (empty($kategoriaa['kategoria_id']))
  95. {
  96. $id_k =1;
  97. }
  98. else
  99. {
  100. $id_k = $kategoriaa['kategoria_id'];
  101. }
  102.  
  103. // Zap2
  104. $kategoria2_sql = 'SELECT * FROM `kategorie` where kategoria_id=' . $id_k;
  105. $kategoria2 = $db->query($kategoria2_sql);
  106. $kategoriaa2 = $kategoria2->fetch_assoc();
  107.  
  108.  
  109.  
  110.  
  111. $news[] = array(
  112. 'nazwa' => znaki('znaki', $newss['nazwa']),
  113. 'id' => $newss['id'],
  114. 'link' => $newss['link'],
  115. 'tresc' => $cutText,
  116. 'autor' => $newss['autor'],
  117. 'data' => $newss['data'],
  118. 'komentarze' => $newse['COUNT( * )'],
  119. 'kategoria' => $kategoriaa2['kategoria_nazwa'],
  120. );
  121. }
  122. $cache->Put('news' . $actualPage, $news, '@queries');
  123. }
  124. foreach ($news as $baza) {
  125. $tpl->set_var('nazwa', $baza['nazwa']);
  126. $tpl->set_var('link', $baza['link']);
  127. $tpl->set_var('id', $baza['id']);
  128. $tpl->set_var('tresc', $baza['tresc']);
  129. $tpl->set_var('autor', $baza['autor']);
  130. $tpl->set_var('data', $baza['data']);
  131. $tpl->set_var('cat', $baza['kategoria']);
  132. $tpl->set_var('coments', $ile_komentarzy->ile($baza['komentarze'], 0)); // Ilosc komentarzy
  133. $tpl->parse("NEWS", true);
  134. }
  135. $tpl->set_var('pager', $pag);
  136.  
  137. include 'hs_header.php'; // Zalaczamy header
  138. $tpl->pparse($nazwa_plikuu, false); // Prasujemy plik
  139. include 'hs_stopka.php'; // Zalaczamy stopke



Zapytanie z tymi komentarzami przerobiłbym tak:

  1. SELECT newsy_strony.id,newsy_strony.nazwa,newsy_strony.DATA,newsy_strony.autor,newsy_strony.tresc,newsy_strony.typ,newsy_strony.link, COUNT( komentarze.id ) ilosc
  2. FROM newsy_strony
  3. LEFT JOIN komentarze ON komentarze.id = newsy_strony.id
  4. GROUP BY newsy_strony.id

(kategorie podobnie)
Według mnie to jest bezsensu z tym liczba_komentarzy. To co dałeś wyżej to też jest trochę bez sensu....
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.