更新子表更改上的父表计数器

时间:2011-12-02 18:07:37

标签: php mysql

我的数据库中有三个表来跟踪我的网站类别

首先是cat_parents

`parent_id` `parent_name`   `counter`
 '   1    '  ' web design'  '   1    '

第二个是cat_subs

 `sub_id`  `parent_id` `sub_name`   `counter`
  ' 1   '   '   1    '  '  php  '   '   1   '
  ' 2   '   '   1    '  '  css  '   '   1   '
  ' 3   '   '   1    '  '  xml  '   '   1   '

,第三个是cat_articles

 `article_id`  `sub_id`  
 '  2       '  '  2  '
 '  2       '  '  3  '
 '  3       '  '  1  '

并且有一个文章表,用于保存标题,文本和ID等文章信息 它类似于:    网页设计(parent_cat)> php(sub_cat)> oop编程(article_name)

现在我希望能够通过我在cat_parents表格中删除或添加的每篇文章增加和减少cat_subscat_articles中的计数器

现在我做的事情(我只是写了这个而且它不是我原来的代码所以忽略语法错误)

public function add_article_to_category($article_id , $sub_id ){
$sql = " select `parent_id` from `cat_subs` where `id` = '$sub_id' " ;
$parent_id  = $db->query($sql);

$sql = "update `cat_parents` set `counter` = counter + 1 where `parent_id` = $parent_id ";
$db->query($sql);


$sql = "update `cat_subs` set `counter` = counter + 1 where `sub_id` = $sub_id ";
$db->query($sql);

$sql = "INSERT INTO `cat_articles` ( `sub_id` , `article_id` ) values ('$sub_id' , '$article_id')";
$db->query($sql);
}

你可以看到我必须运行3个不同的查询,并且在删除cus时最糟糕的是我所要做的就是将文章id传递给函数

function delete_from_category($article_id){
$sql = "delete from `cat_articles` where `article_id` = '$article_id' " ; 
}

我甚至不需要在这里的子ID(我不想在这里传递sub_id到查询因为每篇文章可以在许多不同的sub_categorys中我首先我必须得到所有这些,它似乎很多工作  )

有没有更方便的方法呢?

我知道这不对,看起来很蠢!但是这样的事情:

function delete_from_category($article_id){

    $sql = "delete from `cat_articles` where `article_id` = '$article_id' and select 

   `sub_id`from this line and  foreachDelete  {

    update `sub_cats` set `counter` = counter-1 where `sub_id` =  $sub_idFromAboveLine and select `parent_id` 

    and( update `parent_cats` set `counter` = counter-1 where `parent_id` =  $parent_idFromAboveLine ) ))" ; 
}

好的我打算用触发器

这是我的代码是对的吗?

 DELIMITER $$ 

CREATE TRIGGER decrease_counter AFTER DELETE ON cat_article
 FOR EACH ROW BEGIN 
UPDATE cat_subs SET counter= counter-1 WHERE cat_subs.sub_id = cat_article.sub_id ; 
END 
$$ DELIMITER ; 

我应该为cat_parents编写单独的triger,还是我可以使用这个?像:

CREATE TRIGGER decrease_counter AFTER DELETE ON cat_article
 FOR EACH ROW BEGIN 
 UPDATE cat_subs SET counter= counter-1 WHERE cat_subs.sub_id = cat_article.sub_id ;
 FOR EACH ROW BEGIN 
 UPDATE cat_parents SET counter= counter-1 WHERE cat_subs.parent_id=cat_parents.parent_id ;
 END
 END 
$$ DELIMITER ; 

2 个答案:

答案 0 :(得分:1)

首先,您应该使用事务来执行此操作。你有3个以上的查询,每个查询相互依赖。如果一个失败,那么所有这些都会失败。现在,如果您的“插入”失败但更新成功,您最终会得到错误的文章计数。

除此之外,您可以使用trigger来实现此功能。它将捕获cat_articles表上的任何插入/删除,并将自动在cat_parents和cat_subs上运行相应的更新。即使仍然会执行3个查询,您的代码也只会发出一个“插入”或“删除”查询 - DBMS将在后台为您处理剩下的事情。

答案 1 :(得分:1)

这不是存储类别的最佳方式,数据将很快变得多余。

在嵌套集模型http://www.planetkodiak.com/code/hierarchical-data-in-mysql/

上查看这篇文章

嵌套集模型基本上就像这样

Root lft = 1 rgt = 8
    Sub1 = left = 2 rgt = 5
        SubSub1 = left = 3 rgt = 4
    Sub2 = left = 6 rgt = 7

1到8之间的所有内容都是Root的子项,2到5之间的所有内容都是Sub1的子项,依此类推