触发更新后使缓存无效

时间:2016-06-09 21:49:42

标签: mysql triggers

我正在尝试编写一个触发器来使我的故事数据库的单词索引无效。但是我似乎无法弄清楚如何在索引操作期间停止触发器再次触发。我知道我需要放置一个if语句来停止更新,但我似乎无法弄清楚它应该是什么样的。

CREATE TRIGGER trMarkStoryForReindex BEFORE UPDATE ON Chapters
  FOR EACH ROW BEGIN

    -- any update to any chapter invalidates the index for the whole story
    -- we could just periodically flush the story index, but this way is
    -- better.
    SET New.isIndexed = FALSE;
    -- delete the index for that story
    -- It will get rebuilt in at most 15 minutes
    DELETE FROM freq WHERE storyid = NEW.StoryId;
END;

我基本上只有在更新语句中没有设置isIndexed导致触发时才触发触发器。

我的数据模型如下:

章节

  • ID
  • isIndexed
  • StoryId

频率

  • storyid

1 个答案:

答案 0 :(得分:0)

这是我提出的解决方案。我已经在SQL小提琴上测试了它,它似乎有效:

-- Database setup
create table chapters (
  id int unsigned not null auto_increment primary key,
  isIndexed boolean default false,
  storyId int not null,
  index idx_storyId(storyId)
);

create table freq (
  word varchar(50),
  storyId int not null,
  index idx_storyId(storyId)
);

delimiter //
create trigger bi_chapters before update on chapters
for each row
begin
  if new.isIndexed = false then
    delete from freq where storyId = new.storyId;
  end if;
end //
delimiter ;

insert into freq(word, storyId) 
values ('one', 1), ('two', 1), ('three', 2);

insert into chapters(isIndexed, storyId) 
values (true, 1), (true, 2);

当您从freq(在更新chapters之前)中选择值时,您会得到以下信息:

select * from chapters;

| id | isIndexed | storyId |
|----|-----------|---------|
|  1 |     false |       1 |
|  2 |      true |       2 |

select * from freq;

|  word | storyId |
|-------|---------|
|   one |       1 |
|   two |       1 |
| three |       2 |

现在,再次update来自select的章节和freq

update chapters
  set isIndexed = false
  where storyId = 1;
select * from freq;

|  word | storyId |
|-------|---------|
| three |       2 |

我做的唯一修改是if块检查新行是否更新为false。如果我正确地理解了你的问题,那就可以满足你的需要。