Mysql - 触发器/视图
触发器在之前的项目中, 应用的着实不多, 没有办法的时候, 才会去用这个. 因为这个东西在后期并不怎么好维护, 也容易造成紊乱.
我最近的项目中, 由于数据库设计(别人设计的)原因, 导致一些最简单功能, 查询起来, 都很麻烦和复杂. 牵涉表非常多, 表与表之间又互有部分关系. 我想说, 这是我见过的最糟糕的数据库设计了. 最后没办法, 公司架构师给了触发器的解决方案.
一、触发器
在项目中, 我新建了一张关系表, 把一些必要的, 有效的关系, 通过触发器的方式, 更新到一张表中, 并在这张表里面建了索引. 然后读取数据的时候, 就通过连接这张关系表, 去得到最后的有效数据. 看上去, 有点类似于读写分离的赶脚, 不过这并不是多台数据库服务器间的.
由于工作的关系, 我不能使用项目中的数据库来做记录, 那就自己搞几个表来玩玩吧. 先建三张表
CREATE TABLE `tch_teacher` (
`Id` INT (11) NOT NULL AUTO_INCREMENT,
`Sex` SMALLINT (6) DEFAULT NULL,
`BId` VARCHAR (36) DEFAULT NULL,
`No` VARCHAR (20) DEFAULT NULL,
`Name` VARCHAR (30) DEFAULT NULL,
`IsDeleted` bit (1) DEFAULT b '' PRIMARY KEY (`Id`),
KEY `Index_Sex` (`Sex`) USING BTREE,
KEY `Index_BId` (`BId`) USING BTREE
) ENGINE = INNODB AUTO_INCREMENT = 21 DEFAULT CHARSET = latin1; CREATE TABLE `tch_contact` (
`Id` INT (11) NOT NULL AUTO_INCREMENT,
`TId` INT (11) DEFAULT NULL,
`QQ` VARCHAR (15) DEFAULT NULL,
`Weixin` VARCHAR (50) DEFAULT NULL,
`Phone` VARCHAR (15) DEFAULT NULL,
PRIMARY KEY (`Id`),
KEY `Index_TId` (`TId`) USING BTREE
) ENGINE = INNODB AUTO_INCREMENT = 11 DEFAULT CHARSET = latin1 COMMENT = '联系方式表'; CREATE TABLE tch_all (
Id INT NOT NULL,
Sex SMALLINT,
BId VARCHAR (36),
NO VARCHAR (20),
NAME VARCHAR (30),
QQ VARCHAR (15),
Weixin VARCHAR (50),
Phone VARCHAR (15)
) COMMENT '完整表';
我这里就通过触发器的方式, 来维护tch_all这张表. 例子不好, 主要是介绍功能, 见谅.
delimiter $
drop trigger if EXISTS tg_insert_all;
create trigger tg_insert_all after insert on tch_teacher for each ROW
BEGIN
insert into tch_all(Sex,BId,NO,NAME) values(new.sex, new.bid, new.no, new.name);
end $
delimiter;
1. 语法
create trigger 触发器名 before/after insert/update/delete on 表名 for each row
begin
end
1. 触发时机 before/after
这里的触发器, 触发的时机是在tch_teacher表数据插入之后. 也就是说, tch_teacher插入成功了之后, 才会向tch_all表插入数据. 这里有一个点需要注意下. 在tch_teacher插入成功后, 向tch_all插入的时候报错, 那么tch_teacher的新插数据就回被回滚.
有插入后触发, 自然就有插入前触发, 只需要将after改成before即可.
before触发, 则会先想tch_all插入数据, 再向tch_teacher插入数据. 插入过程中, 不管哪一步失败, 都会回滚数据. 所以不需要担心, 触发不成功的情况下, 会不会造成冗余或者错误数据.
2. 触发方式 insert/update/delete
触发方式, 有插入/修改/删除 时触发. 例子中我只写了插入触发别的两种方式的使用方法是和这个一样的.
3. 原数据引用 old/new
这里有一个问题, 我修改了数据, 那么我怎么引用他们呢? 既然修改了数据, 那肯定是有 修改前数据和修改后新数据 的引用的,
这里直接使用 old 来指向修改前的数据, new 指向修改后的数据. 这里的指向, 是指向的tch_teacher中的数据, 不是tch_all的数据.
4. 注
例子中, 我只用了一句话, 例子嘛, 简单就好. 其实在实际使用过程之中, 不会是这么简单的. 举个例子说吧.
很多时候, 由于数据重要性, 不会直接删除数据. 而是选择更新数据状态来表示其已不再使用. 这里就用 isdeleted来表示, 0表示能用, 1表示不再使用.
当我更新tch_teacher的isdeleted的值为1的时候, 触发修改触发器, 在触发器中, 我就需要判断 new.isdeleted的值, 从而选择是否删除关系表中的数据.
delimiter $
DROP TRIGGER IF EXISTS tg_update_all ;
CREATE TRIGGER tg_update_all AFTER UPDATE ON tch_teacher FOR EACH ROW
BEGIN
IF new.isdeleted = 1 THEN
DELETE FROM tch_all WHERE id = old.id ;
ELSE
UPDATE tch_all set sex=new.sex, bid=new.bid, NO=new.NO, NAME=new.NAME where id = old.id;
END IF ;
END$
delimiter ;
到这里, 我发现好像没有继续这个例子的必要了, 好吧, 那就这样了.
二、视图
视图的作用: 简化查询, 提升查询速度.
老版本的mysql, 并不支持视图子查询, 但是新版本的mysql, 已经能支持了.
就上面这个例子而言, 其实也可以使用视图的方式, 去解决复杂的逻辑.
单是就查询性能上来说, 我觉得还是触发器的方式快一些. 毕竟触发器维护了一张新表, 而且新表能够建索引来提升查询速度. 就是维护起来比较麻烦.
delimiter $
drop view if EXISTS v_all; -- 删除视图
create view v_all AS -- 新建视图
select tch_teacher.*,tch_contact.QQ,tch_contact.Weixin,tch_contact.Phone from tch_teacher
left join tch_contact on tch_teacher.Id=tch_contact.TId where tch_teacher.IsDeleted=0 $
delimiter;
这里我使用到了一个东西:delimiter, 这个在mysql中, 是用来分割的.
"delimiter $" 到 "$ delimiter;" 之间的东西是独立的. 所以, 如果将触发器的脚本和视图的脚本放在一个脚本中去执行, 是能够执行的.
如果是单个执行, 就不需要加那个了.
Mysql - 触发器/视图的更多相关文章
- Day4 MySql触发器视图索引以及设计优化
触发器 MySQL包含对触发器的支持.触发器是一种与表操作有关的数据库对象,当触发器所在表上出现指定事件时,将调用该对象,即表的操作事件触发表上的触发器的执行. 通过事件触发,不能传参 语法 CREA ...
- MySQL笔记---视图,存储过程, 触发器的使用入门
大二学数据库的时候,只是隐约听到老师提起过视图啊,存储过程啊,触发器啊什么的,但只是淡淡的记住了名字,后来自己做些小项目,小程序,也没有用上过,都只是简单的建表,关联表之类的,导致我对这些东西的理解只 ...
- mysql 查询表,视图,触发器,函数,存储过程
1. mysql查询所有表: SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = '数据库名' AND TAB ...
- MySQL之视图、触发器、事务、存储、函数、流程控制
一.视图 视图就是一个虚拟表,我们把复杂的sql语句后看到的虚拟表封装起来,给他取个名字,当我们下次使用的时候,就不用再去写复杂的sql语句,直接调用封装后的视图名字,就可以得到我们想要的表,然后就可 ...
- MySQL之视图、触发器、事务、存储过程、函数 流程控制
MySQL之视图.触发器.事务.存储过程.函数 阅读目录 一 视图 二 触发器 三 事务 四 存储过程 五 函数 六 流程控制 MySQL这个软件想将数据处理的所有事情,能够在mysql这个层面上全部 ...
- 数据库MySQL之 视图、触发器、存储过程、函数、事务、数据库锁、数据库备份、事件
数据库MySQL之 视图.触发器.存储过程.函数.事务.数据库锁.数据库备份.事件 浏览目录 视图 触发器 存储过程 函数 事务 数据库锁 数据库备份 事件 一.视图 1.视图概念 视图是一个虚拟表, ...
- MySQL 的视图、触发器、事务、存储过程、函数
MySQL 的视图.触发器.事务.存储过程.函数 阅读目录 一 视图 二 触发器 三 事务 四 存储过程 五 函数 六 流程控制 一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句 ...
- day 40 MySQL之视图、触发器、事务、存储过程、函数
MySQL之视图.触发器.事务.存储过程.函数 阅读目录 一 视图 二 触发器 三 事务 四 存储过程 五 函数 六 流程控制 MySQL这个软件想将数据处理的所有事情,能够在mysql这个层面上 ...
- mysql第五篇 : MySQL 之 视图、触发器、存储过程、函数、事物与数据库锁
第五篇 : MySQL 之 视图.触发器.存储过程.函数.事物与数据库锁 一.视图 视图是一个虚拟表(非真实存在的),其本质是‘根据SQL语句获取动态的数据集,并为其命名‘ ,用户使用时只需使用“名称 ...
随机推荐
- [APUE]标准IO库(上)
一.流和FILE对象 系统IO都是针对文件描述符,当打开一个文件时,即返回一个文件描述符,然后用该文件描述符来进行下面的操作,而对于标准IO库,它们的操作则是围绕流(stream)进行的. 当打开一个 ...
- Angular企业级开发(4)-ngResource和REST介绍
一.RESTful介绍 RESTful维基百科 REST(表征性状态传输,Representational State Transfer)是Roy Fielding博士在2000年他的博士论文中提出来 ...
- javascript动画系列第一篇——模拟拖拽
× 目录 [1]原理介绍 [2]代码实现 [3]代码优化[4]拖拽冲突[5]IE兼容 前面的话 从本文开始,介绍javascript动画系列.javascript本身是具有原生拖放功能的,但是由于兼容 ...
- 非技术1-学期总结&ending 2016
好久好久没写博客了,感觉动力都不足了--12月只发了一篇博客,好惭愧-- 今天是2016年最后一天,怎么能不写点东西呢!! 学期总结 大学中最关键一年的第一个学期,共4个月.前20天在学网络方面的,当 ...
- LeetCode - Two Sum
Two Sum 題目連結 官網題目說明: 解法: 從給定的一組值內找出第一組兩數相加剛好等於給定的目標值,暴力解很簡單(只會這樣= =),兩個迴圈,只要找到相加的值就跳出. /// <summa ...
- AutoIt实现Webdriver自动化测试文件上传
在运用WebDriver进行自动化测试时,由于WebDriver自身的限制,对于上传文件时Windows弹出的文件选择窗口无法控制,通过在网上查找资料锁定使用AutoIt来控制文件上传窗口. Auto ...
- Python处理Excel表格
同事小王今天说他有一个Excel表格,表格如下,一列是姓名,一列是电话号码,总共有大概2000行数据. 有的姓名占了一行,有的占了两行,还有一些占了三行的.如下图: 他问我可不可以全部统一成一行,而且 ...
- 通过几个Hello World感受.NET Core全新的开发体验
2016年6月27日,这是一个特殊的日子,微软全新的.NET开发平台.NET Core的RTM版本正式发布.我个人将.NET Core的核心特性归结为三点,它们的首字母组成一个非常好记的简称——COM ...
- 在 Linux 中使用 Git 及其 和 Eclipse 的集成
##参考资料## 我是通过阅读<Pro Git>这本书学习 Git 的,我读的时候还是第一版的英文版,现在已经出第二版了,而且英文版和中文版都有.英文第二版的地址是 [https://gi ...
- [Intel Edison开发板] 04、Edison开发基于nodejs和redis的服务器搭建
一.前言 intel-iot-examples-datastore 是Intel提供用于所有Edison开发板联网存储DEMO所需要的服务器工程.该工程是基于nodejs和redis写成的一个简单的工 ...