当我在 post 上插入新评论时,如何在 MYSQL 中创建触发器作为计数器

How to make trigger in MYSQL that acts as counter when I insert new comment on my post

我想知道如何更新列 numberOfComments 以显示在 post 上发表的评论数。我可以在 table comments 上创建触发器并更新 table [=23 中的列 numberOfComments =]s? 表格看起来像这样。

create table posts (
   post_id int primary key,
   post_subject varchar(255),
   numberOfComments int);

create table comments(
   comment_id int primary key,
   comment_text,
   post_id int,
   foreign key (post_id) references posts(post_id));

通常,最好让您的查询生成这些类型的数字,而不是设置触发器。你可以用这样的东西来做

  SELECT p.post_id, p.post_subject, COALESCE(c.ccount) numberOfComments
   FROM posts p
   LEFT JOIN (
                SELECT post_id, COUNT(*) ccount
                  FROM comments
                 GROUP BY post_id
              ) c ON p.post_id = c.post_id;

SQL就是为这种查询而生的;它的性能出奇地好,尤其是对于您使用的主键。如果您想了解更多关于性能良好的原因,您可以阅读松散索引扫描

您可以在数据库中创建一个视图,其结果与您建议的 table 相同,例如

CREATE VIEW post_with_comment_count AS
  SELECT p.post_id, p.post_subject, COALESCE(c.ccount) numberOfComments
   FROM posts p
   LEFT JOIN (
                SELECT post_id, COUNT(*) ccount
                  FROM comments
                 GROUP BY post_id
              ) c ON p.post_id = c.post_id;

为什么这是解决您问题的好方法?它比触发器更容易阅读和维护,更不容易失败,并且 declarative 而不是 程序。

如果您发现这种方法的性能很差,您可以采用不同的方法。但是,除非你有数百万的帖子和评论,否则你不会到达那里。在那之前,保持简单。

我同意其他答案和评论,即使用触发器来保持评论数量完美更新是很棘手的。您会认为这会很可靠,但实际上并非如此。

但为了回答您的问题,这里有一个演示:

我按照你在问题中显示的那样创建了表格,然后在帖子中添加一行:

insert into posts set post_id = 1, post_subject = 'subject';

触发器如下:

create trigger updNumberOfComments after insert on comments 
for each row 
  update posts set numberOfComments = COALESCE(numberOfComments, 0) + 1 
  where post_id = NEW.post_id;

这个触发器只是一个语句,所以我能够在没有 BEGIN...END 块的情况下编写它。但是如果你做任何需要块的事情,那么你应该阅读 using DELIMITER.

再补充几句:

insert into comments set comment_id = 1, comment_text = 'comment 1', post_id = 1;
insert into comments set comment_id = 2, comment_text = 'comment 2', post_id = 1;
insert into comments set comment_id = 3, comment_text = 'comment 3', post_id = 1;

确认它增加了评论的数量:

select * from posts;
+---------+--------------+------------------+
| post_id | post_subject | numberOfComments |
+---------+--------------+------------------+
|       1 | subject      |                3 |
+---------+--------------+------------------+

您可以使用 mysql 触发器,与 select 或连接查询不同,它们会一直存在于您的数据库中,直到它们被删除。

DROP TRIGGER IF EXISTS `comment_count_incrementer`;

DELIMITER $$

CREATE TRIGGER `comment_count_incrementer`AFTER INSERT ON comments 
  FOR EACH ROW 
    BEGIN
      UPDATE posts 
      SET numberofComments = CASE numberOfComments
                               WHEN IS NULL THEN 1
                               ELSE numberofComments + 1
                             END
      WHERE posts.post_id = comments.post_id;
    END$$

DELIMITER ;

以上是如何实现触发器的要点