视图
- 什么是视图?
- 为什么使用视图?
使用视图是为了方便复杂的查询语句。基本思路是将复杂的查询语句定义在视图内部,然后对视图进行查询,从而简化复杂的查询语句。 - 应用场景
- 多个地方用到同样的查询结果。
- 该查询结果使用的sql语句复杂。
- 定义视图
create view 视图名 as 查询语句
例如:
-- 创建视图
CREATE VIEW sel_news AS
SELECT a.id,a.account,a.password FROM admin a
优点
- 重复使用sql语句。
- 简化了复杂的sql操作。
- 保护数据,提高安全性。
- 视图修改
语法一:
-- 修改视图语法一:
CREATE OR REPLACE VIEW sel_news AS
SELECT a.id,a.account,a.sex FROM admin a
语法二:
-- 修改视图语法二:
ALTER VIEW sel_news AS
SELECT a.id,a.account,a.phone FROM admin a
- 视图删除
语法:
-- 删除视图
DROP VIEW sel_news
- 使用视图
语法:
-- 使用视图
SELECT * FROM sel_news
- 查看视图
语法一:
-- 查看输入
DESC sel_news
语法二:
-- 查看输入语法2
SHOW CREATE VIEW sel_news
- 视图更新
插入数据:
insert into 视图名 () values();
修改数据
update 视图名 set 列名=();
删除数据
delete from 视图名 where 条件
视图更新的可更新性与视图中查询的定义有关系下面这几种类型的视图是不能更新的
- 表与视图的对比
视图 | 表格 |
---|---|
create view | create table |
基本上不占用内存(保存逻辑) | 占用内存(保存数据) |
可以增删改查(一般不能增删改) | 可以增删改查 |
存储过程
-
概述
对数据库的认知:里面可以以表存数据,使用sql语言,操作数据。数据库中也可以向Java语言一样有逻辑处理功能。
事先被编写好,储存在数据库中,使用时直接调用即可。
-
优点:
处理某一个逻辑的过程直接存储在数据库中,运行速度快。 -
缺点:
对数据库的依赖程度较高,移植性差。
- 创建存储过程的语法格式
-- 存储过程
DELIMITER $$
CREATE
PROCEDURE 存储过程([in 变量名,out参数2,...])
-- 存储过程体
BEGIN
-- DECLARE用来声明变量的
DECLARE 变量名 类型 [DEFAULT 值];
存储过程语句块
END$$
DELIMITER ;
例如:
-- 查询管理员类型为1的有几条 演示入参和出参
DELIMITER $$
CREATE
PROCEDURE type_count(IN p_typeid INT, OUT p_count INT)
-- 存储过程体
BEGIN
SELECT COUNT(*) INTO p_count FROM admin WHERE TYPE=p_typeid ; -- 测试输出语句
SELECT p_count;
END$$
DELIMITER ;
- 流程控制语句 if else
DELIMITER$$
CREATE PROCEDURE test(IN p_day INT)
BEGIN
IF p_day=0 THEN
SELECT "星期天";
ELSEIF p_day=1 THEN
SELECT "星期一";
ELSEIF p_day=2 THEN
SELECT "星期二";
ELSE
SELECT "无效日期";
END IF;
END$$
测试
CALL test(2)
- mybatis调用存储过程插入信息
- 创建带参的存储过程
-- 存储过程保存管理员,在存储过程中判断账号是否已经存储,不存在存储,则返回账号以存在
DELIMITER $$
CREATE
PROCEDURE save_admin(IN p_account VARCHAR(11),IN p_password VARCHAR(50),OUT p_result VARCHAR(10))
BEGIN
-- 声明一个变量,接收查询到的结果
DECLARE v_count INT DEFAULT 0;
SELECT COUNT(*) INTO v_count FROM admin WHERE account=p_account;
IF v_count =0 THEN
INSERT INTO admin(account,PASSWORD)VALUES(p_account,p_password);
SET p_result="保存成功";
SELECT p_result;
ELSE
SET p_result ="账号已存在";
SELECT p_result;
END IF;
END$$
DELIMITER ;
- mybaits调用这个存储过程
adminDao
//测试存储过程
void saveAdmins(Map<String,Object> map);
AdminMapper.xml
<parameterMap id="adminmap" type="map">
<parameter property="account" jdbcType="VARCHAR" mode="IN"></parameter>
<parameter property="password" jdbcType="VARCHAR" mode="IN"></parameter>
<parameter property="result" jdbcType="VARCHAR" mode="OUT"></parameter>
</parameterMap>
<insert id="saveAdmins" parameterMap="adminmap" statementType="CALLABLE">
{CALL save_admin(?,?,?)}
</insert>
测试类
public class TestSaveAdmin {
@Test
public void saveAdmins() {
SqlSession sqlSession= MybatisUtil.getSqlSession();
AdminMapper mapper=sqlSession.getMapper(AdminMapper.class);
HashMap<String,Object>map=new HashMap<>();
map.put("account","tomcat3");
map.put("password","123");
mapper.saveAdmins(map);
System.out.println(map.get("result"));
sqlSession.commit();
sqlSession.close();
}
}
运行结果
- 对AdminMapper.xml中的一些解析
函数
语句:
DELIMITER $$
create function 函数名([参数列表]) returns 数据类型
begin
DECLARE 变量;
sql 语句;
return 值;
end;
DELIMITER ;
不带参函数
创建函数
# 查询admin表中的总数
DELIMITER $$
CREATE FUNCTION demo() RETURNS INT
BEGIN
DECLARE v_count INT DEFAULT 0;
SELECT COUNT(*) INTO v_count FROM admin;
RETURN v_count;
END$$
DELIMITER ;
使用函数
SELECT demo()
结果
带参函数
创建函数
DELIMITER $$
CREATE FUNCTION findType(p_type INT) RETURNS VARCHAR(10)
BEGIN
DECLARE v_type VARCHAR(10) DEFAULT '';
IF p_type= 0 THEN
SET v_type='超级管理员';
ELSE
SET v_type='管理员';
END IF;
RETURN v_type;
END$$
DELIMITER ;
使用函数
SELECT account,id,findType(TYPE)TYPE FROM admin
结果
与不调用函数对比
SELECT account,id,TYPE FROM admin
触发器
触发器(trigger)是一种特殊的存储过程,其特殊性在于它并不需要用户直接调用,而是在对表添加、修改、删除之前或者之后自动执行的存储过程。
特点
-
与表相关联
触发器定义在特定的表上,这个表称为触发器表.
-
自动激活触发器
当对表中的数据数据执行insert, update,或delete操作时 如果对表上的这个特定操作定义了触发器,该触发器自动执行,这是不可撤销的
-
不能直接调用
与存储过程不同,触发器不能被直接调用,也不能传递或接收参数
-
作为事物的一部分
触发器与激活触发器的语句一起为对一个单一的事务来对待 可以从触发器的任何位置回滚
定义触发器
-- 触发器
DELIMITER $$
CREATE
TRIGGER 触发器名称 触发时机 触发事件
ON 表名
FOR EACH ROW -- 行级触发 操作多行时每行都会触发
BEGIN
语句
END$$
DELIMITER ;
语法解析
1.触发器名称:是用来标识触发器的,由用户自定义。
2.触发时机:其值是 before 或 after。
3.触发事件:其值是 insert,update 和 delete
4.表名称:标识建立触发器的表名,即在哪张表上建立触发器
5.语句:是触发器程序体,触发器程序可以使用 begin 和 end 作为开始和结束,
中间包含多条语句;
案例
删除管理员触发删除管理员与角色的关联关系
-- 触发器
DELIMITER $$
CREATE TRIGGER delete_admin_role
BEFORE
DELETE
ON admin
FOR EACH ROW -- 行级触发 操作多行时每行都会触发
BEGIN
DELETE FROM admin_role WHERE adminId=old.id;
END$$
DELIMITER ;
效果展示
DELETE FROM admin WHERE id =48
案例
每当我向admin表中插入一条数据,就像admin_log表中插入一条日志记录
-- 每当我向admin表中插入一条数据,就像admin_log表中插入一条日志记录
DELIMITER $$
CREATE TRIGGER save_adminLog
AFTER
INSERT
ON admin
FOR EACH ROW -- 行级触发 操作多行时每行都会触发
BEGIN
INSERT INTO admin_log(id,account,oper_time)VALUES(new.id,new.account,NOW());
END$$
DELIMITER ;
INSERT INTO admin(account,PASSWORD)VALUES('test001','1111');
MySQL架构
MySQL的完整构架图
连接层
服务层
引擎层
MySQL引擎
引擎是什么
MySQL有哪些常见的引擎
常用的引擎
MyiSam 不支持事务 查询多使用 支持外键
不支持行锁,支持表锁,支持全文索引,存储表的总行数
Inn0db 支持事务 增删改多使用 支持表锁、行锁、
支持缓存、支持主键自增,支持全文索引,不存储表的总行数
查看支持的引擎
-- 查看支持的引擎
SHOW ENGINES
查看表引擎
SHOW TABLE STATUS LIKE 'admin'
修改引擎
方式 1:将 mysql.ini 中 default-storage-engine=InnoDB,重启服务.
方式 2:建表时指定 CREATE TABLE 表名(...)ENGINE=MYISAM;
方式 3:建表后修改 ALTER TABLE 表名 ENGINE = INNODB
索引
在学习数组的时候,我们知道可以通过索引快速的找到某个索引位置的数据。
为什么要有索引?
什么是索引?
索引原理
索引优势
索引劣势
索引分类
-
主键索引
设定为主键后数据库会自动建立索引
ALTER TABLE 表名 add PRIMARY KEY 表名(列名);
#删除建主键索引:
ALTER TABLE 表名 drop PRIMARY KEY
-
单值索引:
一个索引包含一个列 、一个表可以有多个单值索引。
-- 创建单值索引
CREATE INDEX 索引名 ON 表名(列名);
CREATE INDEX admin_account ON admin(account);
删除索引:
DROP INDEX 索引名
-
唯一索引:
索引列的数据不能重复,允许为null
创建唯一索引
CREATE UNIQUE INDEX 索引名 ON 表名(列名);
删除索引
DROP INDEX 索引名 ON 表
-
组合索引(复合索引):
一个索引包含多个列, 当表的行数远大于索引列的数目时可以使用。 开销更小
创建复合索引
CREATE INDEX 索引名 ON 表名(列 1,列 2...);
删除索引:
DROP INDEX 索引名 ON 表名;
组合索引最左前缀原则
组合索引最左前缀原则
使用组合索引时,要出现最左列(组合索引里的最左列)在这里理解的
使用模糊查询 name like '%张% ; 这样的写法会导致name列的索引失效 like的模糊查询不建议这样使用
MySQL8中建议使用 全文索引
全文索引
CREATE FULLTEXT INDEX 索引名 ON 表名(字段名) WITH PARSER ngram;
SELECT 结构 FROM 表名 WHERE MATCH(列名) AGAINST(搜索词')
查看索引:
SHOW INDEX FROM 表名
索引创建原则
索引也是一把双刃剑,因此不能随便使用。
-
什么时候需要创建索引?
1. 主键自动建立唯一约束 主键索引 2. 作为查询条件的列 适合创建索引 3. 外键建议建立索引 4. 排序的字段、分组的字段
-
什么情况不建议使用索引?
1. 表数据太少 2. 经常更新的表(增删改) 3. 不是查询条件的字段 4. 数据重复且分布均匀的字段 例如(性别)
索引数据结构
聚簇索引和非聚簇索引
-
聚簇索引
1.找到了索引就找到了数据,这就是聚簇索引 2.主键可以直接找到数据 3.根据学号只查找学号 可以直接命中学号 此种场景学号就是聚簇的
-
非聚簇索引
1. 找到了索引但没有找到数据,需要根据主键再次回表查询 2. 根据学号查询学号、姓名 虽然学号加了索引但还是需要查询姓名 需要根据学号,找到主键,通过主键回表查询 此种场景就是聚簇的