Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP][AJAX] Wydajny shoutbox, shoutbox oparty na procedurach
CuteOne
post 8.02.2013, 10:30:13
Post #1





Grupa: Zarejestrowani
Postów: 2 958
Pomógł: 574
Dołączył: 23.09.2008
Skąd: wiesz, że tu jestem?

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


Witam,

ponieważ wystąpiły pewne komplikacje z edycją poprzedniego tematu, ponownie zamieszczam przykład wykorzystania procedur w celu zwiększenia wydajności naszych aplikacji. Przykład jak sam tytuł wskazuje, odnosi się do najbardziej zasobożernego elementu większości stron - shoutboxie opartym na AJAX'ie.

Poniżej przedstawiam archiwum z przykładem wydajnego shoutboxa. W przeciwieństwie do innych topików w tym dziale nie jest to gotowiec a sposób w jaki możemy wykorzystać wbudowane elementy MySQL'a. Przydatne na serwerach współdzielonych, które domyślnie nie obsługują memcache, a mają narzucone restrykcje typu "użyj czegoś co zamuli serwer a będziemy musieli się pożegnać".


Link do archiwum:
RapidShare

1. Tworzymy nowe tabele w naszej bazie danych (wrzucamy poniższe zapytania do MySQL np. za pomocą phpmyadmin)
  1. --
  2. -- Struktura tabeli dla tabeli `chat_posts`
  3. --
  4.  
  5. DROP TABLE IF EXISTS `chat_posts`;
  6. CREATE TABLE IF NOT EXISTS `chat_posts` (
  7. `post_id` int(4) UNSIGNED NOT NULL AUTO_INCREMENT,
  8. `user_id` int(4) UNSIGNED NOT NULL,
  9. `post_text` varchar(300) NOT NULL,
  10. `date_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  11. PRIMARY KEY (`post_id`,`user_id`)
  12. ) ENGINE=MEMORY DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
  13.  
  14. -- --------------------------------------------------------
  15.  
  16. --
  17. -- Struktura tabeli dla tabeli `chat_users`
  18. --
  19.  
  20. DROP TABLE IF EXISTS `chat_users`;
  21. CREATE TABLE IF NOT EXISTS `chat_users` (
  22. `user_id` int(4) UNSIGNED NOT NULL AUTO_INCREMENT,
  23. `user_name` varchar(15) NOT NULL,
  24. `user_avatar` varchar(50) NOT NULL,
  25. `post_id` int(4) UNSIGNED NOT NULL,
  26. `flag_status` tinyint(1) NOT NULL,
  27. PRIMARY KEY (`user_id`),
  28. UNIQUE KEY `user_name` (`user_name`)
  29. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=5 ;
  30.  
  31. --
  32. -- Zrzut danych tabeli `chat_users`
  33. --
  34.  
  35. INSERT INTO `chat_users` (`user_id`, `user_name`, `user_avatar`, `post_id`, `flag_status`) VALUES
  36. (1, 'Songo', 'default.jpg', 0, 1),
  37. (2, 'Vegeta', 'default.jpg', 22, 1),
  38. (3, 'Gohan', 'gohan.gif', 22, 1),
  39. (4, 'Cell', 'cell.jpg', 22, 1);



2. W podobny sposób dodajemy procedury
  1. DELIMITER $$
  2. --
  3. -- Procedury
  4. --
  5. CREATE PROCEDURE `sp_clean`()
  6. BEGIN
  7. DECLARE cnt, cur INT;
  8.  
  9. SET cnt = (SELECT COUNT(*) FROM `chat_posts`);
  10.  
  11. IF cnt > 20 THEN
  12. SET cur = (SELECT `post_id` FROM `chat_posts` ORDER BY `post_id` DESC LIMIT 19,1);
  13. DELETE FROM `chat_posts` WHERE `post_id` < cur;
  14. END IF;
  15. END$$
  16.  
  17. CREATE PROCEDURE `sp_connect`(IN `pUserId` INT(4))
  18. BEGIN
  19. DECLARE userName VARCHAR(15);
  20. DECLARE postId INT;
  21. SET userName = (SELECT `user_name` FROM `chat_users` WHERE `user_id`=pUserId);
  22.  
  23. #udate post_id
  24. UPDATE `chat_users` SET `post_id`=(SELECT MAX(`post_id`) FROM `chat_posts`);
  25.  
  26. #insert connect message
  27. CALL sp_insert(pUserId, CONCAT(userName, ' dołączył do czatu'));
  28. END$$
  29.  
  30. CREATE DEFINER=`root`@`localhost` PROCEDURE `sp_disconnect`(IN `pUserId` INT(4))
  31. BEGIN
  32. DECLARE userName VARCHAR(15);
  33. SET userName = (SELECT `user_name` FROM `chat_users` WHERE `user_id`=pUserId);
  34.  
  35. #udate post_id
  36. UPDATE `chat_users` SET `post_id`=0 WHERE `user_id`=pUserId;
  37.  
  38. #insert disconnect message
  39. CALL sp_insert(pUserId, CONCAT(userName, ' odłączył się od czatu'));
  40. END$$
  41.  
  42. CREATE PROCEDURE `sp_fetch`(IN `pUserId` INT(4))
  43. BEGIN
  44. DECLARE postId, maxPostId INT;
  45. SET postId = (SELECT `post_id` FROM `chat_users` WHERE `user_id`=pUserId);
  46. SET maxPostId = (SELECT MAX(`post_id`) FROM `chat_posts`);
  47.  
  48. CALL sp_update_id(pUserId, maxPostId);
  49.  
  50. SELECT
  51. `p`.`post_text`, TIME(`p`.`date_create`) AS time_create,
  52. `u`.`user_id`, `u`.`user_name`, `u`.`user_avatar`
  53. FROM
  54. `chat_posts` `p`,
  55. `chat_users` `u`
  56. WHERE
  57. `p`.`user_id` = `u`.`user_id` AND
  58. `p`.`post_id` > postId
  59. ORDER BY `p`.`post_id` ASC
  60. LIMIT 10;
  61. END$$
  62.  
  63. CREATE PROCEDURE `sp_insert`(IN `pUserId` INT(4), IN `pPostText` VARCHAR(300) CHARSET utf8)
  64. BEGIN
  65. DECLARE insertId INT;
  66.  
  67. INSERT INTO `chat_posts` (`user_id`, `post_text`) VALUES (pUserId, pPostText);
  68. SET insertId = LAST_INSERT_ID();
  69.  
  70. #CALL sp_update_id(pUserId, insertId-1);
  71. CALL sp_remove();
  72. CALL sp_fetch(pUserId);
  73. END$$
  74.  
  75. CREATE PROCEDURE `sp_remove`()
  76. BEGIN
  77. DECLARE cnt, postId INT;
  78.  
  79. SET cnt = (SELECT COUNT(*) FROM `chat_posts`);
  80.  
  81. IF cnt > 20 THEN
  82. SET postId = (SELECT MIN(`post_id`) FROM `chat_posts`);
  83. DELETE FROM `chat_posts` WHERE `post_id` = postId;
  84. END IF;
  85. END$$
  86.  
  87. CREATE PROCEDURE `sp_update_id`(IN `pUserId` INT(4), IN `pPostId` INT(4))
  88. BEGIN
  89. UPDATE `chat_users` SET `post_id`=pPostId WHERE `user_id`=pUserId;
  90. END$$
  91.  
  92. DELIMITER ;



3. Opcjonalnie, możemy dodać zdarzenie, które co godzinę będzie czyściło naszą tabelę z ewentualnego nadmiaru postów
  1.  
  2. DELIMITER $$
  3. --
  4. -- Zdarzenia
  5. --
  6. CREATE EVENT `task_clean` ON SCHEDULE EVERY 1 HOUR STARTS '2013-01-01 00:00:00' ENDS '2020-01-01 03:00:00' ON COMPLETION NOT PRESERVE ENABLE DO CALL sp_clean()$$
  7.  
  8. DELIMITER ;



4. Wypakuj wcześniej ściągnięte archiwum i w pliku ajax.php ustaw dane do połączenia z bazą MySQL.
5. Odpal skrypt index.php?id=x gdzie x to user_id z tabeli chat_users

Do poprawnego działania należy zmodyfikować plik ajax.php aby obsługiwał Twój system autoryzacji użytkowników.


------------------------------------------------------------------------------


Poniżej przewaga procedur nad zapytaniami pisanymi w PHP

dodanie rekordu przy pomocy procedury
  1. $query = mysql_query("CALL sp_insert('".$user_id."','".$msg."');");
  2.  
  3. $array = array();
  4. while($row = mysql_fetch_assoc($query)) {
  5. $array[] = $row;
  6. }
  7. echo json_encode($array);



dodanie rekordu przy pomocy zapytań pisanych w php
  1. mysql_query("INSERT INTO `chat_posts` (`user_id`, `post_text`) VALUES ('".$user_id."','".$msg."')");
  2.  
  3. $query = mysql_query("SELECT COUNT(*) FROM `chat_posts`");
  4. $row = mysql_fetch_row($query);
  5.  
  6. if($row[0] > 20) { // jeżeli rekordów jest więcej niż 20, usuń stary wpis
  7.  
  8. $query = mysql_query("SELECT MIN(`post_id`) FROM `chat_posts`");
  9. $row = mysql_fetch_row($query);
  10.  
  11. mysql_query("DELETE FROM `chat_posts` WHERE `post_id` = '".$row[0]."'");
  12. }
  13. // pobranie aktualnego id postu w celu pobrania nowszych rekordów
  14. $query = mysql_query("SELECT `post_id` FROM `chat_users` WHERE `user_id`='".$user_id."'");
  15. $postId = mysql_fetch_assoc($query);
  16.  
  17. // pobranie max. post_id w celu update'u w tabeli chat_users
  18. $query = mysql_query("SELECT MAX(`post_id`) FROM `chat_posts`");
  19. $maxPostId = mysql_fetch_row($query);
  20.  
  21. //update user
  22. mysql_query("UPDATE `chat_users` SET `post_id` = '".$maxPostId."'");
  23.  
  24. // pobranie najnowszych postów
  25. $query = mysql_query("
  26. SELECT
  27. `p`.`post_text`, TIME(`p`.`date_create`) as time_create,
  28. `u`.`user_id`, `u`.`user_name`, `u`.`user_avatar`
  29. FROM
  30. `chat_posts` `p`,
  31. `chat_users` `u`
  32. WHERE
  33. `p`.`user_id` = `u`.`user_id` AND
  34. `p`.`post_id` > '".$postId."'
  35. ORDER BY `p`.`post_id` ASC
  36. LIMIT 10");
  37.  
  38. $array = array();
  39. while($row = mysql_fetch_assoc($query)) {
  40. $array[] = $row;
  41. }
  42. echo json_encode($array);


Ten post edytował CuteOne 8.02.2013, 10:34:53
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 Wersja Lo-Fi Aktualny czas: 18.04.2024 - 07:36