Warning: Cannot use a scalar value as an array in /home/admin/public_html/forum/include/fm.class.php on line 757

Warning: Invalid argument supplied for foreach() in /home/admin/public_html/forum/include/fm.class.php on line 770
Форумы портала PHP.SU :: Версия для печати :: Хранимая процедура. Каунтер.
Форумы портала PHP.SU » PHP » SQL и Архитектура БД » Хранимая процедура. Каунтер.

Страниц (1): [1]
 

1. haveFun - 17 Февраля, 2015 - 04:31:13 - перейти к сообщению
привет!
скажите пожалуйста, можно ли реализовать следующую хотелку, и если да, то как?

есть таблица новостей
news: id; cat_id; title ...

так же есть таблица категорий
cats: id; name; count ...

логическую связь выделил жирным.
хотелось бы что бы при добавлении новости для категории news:cat_id=1, у категории cats:id = 1 увеличивался cats:count на единицу, и соответственно при удалении новости, каунт автоматически уменьшался.

все это безусловно можно вынести в контроллер сайта, но мне бы хотелось реализовать данную задачу на стороне БД.
надеюсь понятно объяснил и кто-нибудь поможет Улыбка

ps:
Server type: MySQL
Server version: 5.5.38 - Source distribution
phpMyAdmin Version information: 4.2.5
2. exlant - 17 Февраля, 2015 - 05:03:36 - перейти к сообщению
А зачем процедуры? можно и без них обойтись!

CODE (SQL):
скопировать код в буфер обмена
  1.  
  2. INSERT INTO NEWS (id,cat_id,title) VALUES ('id','cat_id','title');
  3.  
  4. UPDATE cats SET count = count +1 WHERE id = 'cat_id';
  5.  
  6. // и для DELETE! с начало удаляем, потом делаем UPDATE нужной категории
  7.  

Как то так, если я правильно понял о чем речь...
3. haveFun - 17 Февраля, 2015 - 05:14:29 - перейти к сообщению
на самом деле мне просто физику и синтаксис понять хочется

к тому же при удалении записи через пма, каунт придется менять вручную.
в общем вопрос именно в вынесении данной логики на сторону БД.
4. exlant - 17 Февраля, 2015 - 05:40:18 - перейти к сообщению
PHP:
скопировать код в буфер обмена
  1.  
  2. $DB->query('DROP PROCEDURE IF EXISTS count');
  3. $query = 'CREATE PROCEDURE count (IN id INT, IN cat_id INT, IN title  VARCHAR(255))  
  4.        BEGIN
  5.               INSERT INTO NEWS (id,cat_id,title) VALUES (id,cat_id,title);
  6.               UPDATE cats SET count = count+1 WHERE id = cat_id;        
  7.        END';
  8.  
  9. $DB->query($query); //один раз создали процедуру, оно будет теперь храниться в бд, пока мы ее не удалим
  10.  
  11. $DB->query('CALL count (id,cat_id,title)'); // потом просто вызываем ее с нужными нам параметрами
  12.  
5. Ch_chov - 17 Февраля, 2015 - 06:49:36 - перейти к сообщению
Для таких случаев вместо процедуры удобней использовать триггер:
CODE (SQL):
скопировать код в буфер обмена
  1. CREATE TRIGGER `increment_counter`
  2. AFTER INSERT ON `news`
  3. FOR EACH ROW
  4. UPDATE cats SET cats.count = cats.count + 1 WHERE new.cat_id = cats.id


haveFun пишет:
к тому же при удалении записи через пма, каунт придется менять вручную.

Если вы собираетесь использовать pma в качестве админки, то вам придется отказатся от каких либо сложных схем в базе данных.
(Добавление)
Кстати, тоже самое можно сделать без денормализации:
CODE (SQL):
скопировать код в буфер обмена
  1. SELECT cats.id, cats.name, COUNT(news.id) cnt
  2. FROM cats
  3. LEFT JOIN news ON cats.id = news.cat_id
  4. GROUP BY cats.id;
6. exlant - 17 Февраля, 2015 - 06:56:48 - перейти к сообщению
pma - это я так понял PHPMyAdmin? я и не подумал бы, что кто то его в качестве админки использует Не понял
7. haveFun - 17 Февраля, 2015 - 07:18:52 - перейти к сообщению
повторюсь в третий раз. альтернативные способы меня не интересуют.
Ch_chov, пожалуй мне нужен именно триггер, спасибо, но почему-то при добавлении записи в news вылетает ошибка с текстом корректного инсерта а так же вот это:
CODE (SQL):
скопировать код в буфер обмена
  1. #1054 - Unknown column 'news.cat_id' in 'where clause'


поменял триггер на
CODE (SQL):
скопировать код в буфер обмена
  1. UPDATE `my_db`.`categories`
  2. SET `my_db`.`categories.count` = `my_db`.`categories.count` + 1 WHERE `my_db`.`news.cat_id` = `my_db`.`categories.id`

но это не помогло. каунт не меняется. типы обоих айдишников int(11).

в чем может быть проблема? Однако
(Добавление)
да. пма - это пхпмайадмин. я знаю что это далеко не навикат, но для моих текущих задач он вполне подходит. Хм
8. Ch_chov - 17 Февраля, 2015 - 07:30:53 - перейти к сообщению
haveFun пишет:
#1054 - Unknown column 'news.cat_id' in 'where clause'


news.cat_id - зачем вы s сюда добавили?
9. haveFun - 17 Февраля, 2015 - 07:58:15 - перейти к сообщению
хм, думал опечатка, и там должно быть название текущей таблицы. это что же указатель какой-то?
исправил, теперь все заработало, спасибо!
10. Ch_chov - 17 Февраля, 2015 - 08:00:21 - перейти к сообщению
На удаление новости, тоже желательно триггер сделать..
11. exlant - 17 Февраля, 2015 - 08:14:56 - перейти к сообщению
Давно назревает такой вопрос!
А насколько актуально или неактуально использовать хранимые процедуры и тригеры?
Есть ли смысл переводить все/большинство запросов на сайте в процедуры, а потом просто вызывать их! Или же где лучше использовать процедуру, а где просто запрос к базе?
(Добавление)
Используя данный случай, если админка будет написана на php, для увеличения count лучше использовать заранее подготовленный тригер, или же описать два запроса к базе в php?
Как правильней сделать, и как делается на больших проектах?
12. Ch_chov - 17 Февраля, 2015 - 08:30:31 - перейти к сообщению
Думаю не стоит смешивать в одну кучу процедуры и триггеры. Конкретно в этом случае тригер может быть уместен, если по каким либо причинам обычный подсчёт с JOIN и GROUB BY нельзя использовать. Счетчики это вообще типовой пример применения тригеров.

С процедурами сложнее..
Наверно от архитектуры приложения зависит. Я меня вот ни разу не возникала необходимость использовать хранимые процедуры. А вообще этот вопрос уже обсуждался не раз:

http://www[dot]sql[dot]ru/forum/724491/h[dot][dot][dot]nyh-sql-zaprosov
http://stackoverflow[dot]com/questio[dot][dot][dot]ures-or-php-code
http://stackoverflow[dot]com/questio[dot][dot][dot]re-vs-php-script

На этом форуме тоже:
http://forum.php.su/topic.php?fo...8&topic=5448
13. exlant - 17 Февраля, 2015 - 08:40:23 - перейти к сообщению
Спасибо за информацию, буду ознакамливаться!

 

Powered by ExBB FM 1.0 RC1