(一)应用场景
情形:在进行查询时,有些结果列需要通过复杂而费时的计算得出
场景:如果数据量大,且经常需要查询,可以考虑空间换时间,在表模型中增加冗余的列存储计算结果。
而这种场景,触发器特别适合,它能漂亮地完成任务,而不需要应用进行任务业务修改。
(二)触发器简介
(1)触发器(trigger)是用来保证数据完整性的一种方法,它是与表事件相关的特殊处理过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,当对一个表进行操作(insert,delete,update)时就会激活它执行。
(2)触发器的大致工作原理:
触发器触发时:系统自动在内存中创建 deleted 表或 inserted 表;只读,不允许修改,触发器执行完成后,自动删除。
inserted :保存插入或更新后的记录行;
deleted :保存删除或更新前的记录行;
这样,在触发器处理过程中就可以根据数据来进行相关的计算了。
(三)实例(SQL Server)
我们以将代表星级的数字,转化为相应数据的五角星图标为例。假如我们经常进行的查询是(用户名,星级),则每次查询都需要调用将数字转换成图标的计算。
说明:为了突出结构本身,实例简化了计算本身。(所以如果认为本实例的这个计算这样做多此一举就太对了)
创建示例表模型:
create table test_star(id int primary key, user_name nvarchar(10), star_cnt int)
插入示例数据:
insert into test_star(id, user_name, star_cnt) values(1, '张三', 3)
则我们查询为:
select user_name 用户名, REPLICATE('★', star_cnt) 星级 from test_star
此时,我们通过在表中增加一个冗余字段:
alter table test_star add star_string nvarchar(100)
然后利用触发器,在参与计算的字段有变化时自动计算结果,保存至冗余字段:
我们对触发器的需求描述:
当 star_cnt 有变化时(新增,修改),自动更新 star_string 为相应值的五角星数。
CREATE TRIGGER trigger_star_update
ON test_star
AFTER INSERT, UPDATE -- 插入 或 更新操作时 star_cnt 可能变化
AS
BEGIN
-- 检测参与计算的这列是否更新
if UPDATE(star_cnt)
begin
-- 根据更新后的值更新冗余字段
update test_star set star_string=REPLICATE('★', i.star_cnt)
from test_star, inserted i
where test_star.id = i.id
end
END
GO
此时,我们更新原示例数据,并同样的方式插入示例数据:
update test_star set star_cnt=star_cnt where id = 1
insert into test_star(id, user_name, star_cnt) values(2, '李四', 4)
我们的查询变成了:
select user_name 用户名, star_string 星级 from test_star
从此,再也不用担心查询慢了。
(四)小结一下这样的好处
1、不用更改业务
2、计算压力分散,计算实时性亦有保障
3、查询变得简单