Mysql数据库的高级应用(存储过程,触发器、索引,视图,函数)

MySQL的高级应用

mysql下载和基本使用详见【Mysql数据库与Python


SQL分类:
DDL:数据定义语言(对库、表,和表字段的增删改)
DML:数据操作语言(给表中数据的增删改)
DCL:数据控制语言(权限和安全)
DQL:数据查询语言(所有的查询select)


例:

假设Student表中字段有(username,age,sex)

  • 查询整张表 select *from Student; – (不建议用*,效率低,可以将要查询的字段名写出来)
  • 查询整张表 select (username,age,sex) from Student;
  • 查询整张表,可以写表名.字段名 select(Student.username,Student.age,Student.sex) from Student;

查询条件where

  • between…and…; 再某某之间,前后都包含
  • in(值1,值2); 比如set(10,20,30),就是查询某字段值为10或者20或者30的
  • is null; 判断是否为null,null值参与的数学运算结果都是null.
  • is not null;判断不为null,
  • and or not 逻辑运算符

查询时候可以起别名:
示例:select username as 姓名,age as 年龄 from Student; (as可以省略)

字段可以运算
示例:select username as 姓名,age as 年龄 age+1 as 虚岁 from Student;

去掉字段中重复值
示例:select distinct 字段名 from Student;

根据年龄从大到小展示
asc(默认的),从小到大排列。
desc 从大到小排列
示例:select *from Student order by age desc;

模糊查询like
% 通配任意多个字符
_ 通陪单个任意字符
示例:找出姓名以S开头的学生 select * from Student where username like ‘S%’;
找出姓名中包涵M的学生 select * from Student where username like ‘%M%’;
找出第二个字符为N的学生 select * from Student where username like ‘_N%’;

聚合函数

  • count(字段名); 统计指定列不为null的记录行数 示例select count(*) from Student;
  • max(); select name,max(age) from Student;
  • min();
  • sum();
  • avg(); select avg(age) as 平均年龄 from Student;

分组函数
emp表中(name,deptno,sal)
对某字段分组
select 字段名 from 表名 group by 字段名;
示例:以部门编号deptno,分组,求各部门的总工资
select deptno,sum(sal) from emp group by deptno;
having用法:对分组后的结果再次筛选
选出各个部门总工资大于9000的部门:
select deptno sum(sal) from emp group by deptno having sum(sal)>9000;

where和having区别{
where:是对分组之前的条件筛选。
having:是对分组之后的结果集的再次筛选。
}

分页查询
limit 起始索引,每页展示的条数
每页展示四条:select * from emp limit 0,4;
起始索引=(页码-1)*每页条数;

MySQL中常见的约束

  • 主键约束 primary key 非空且唯一,一种表只能由一个主键
  • 非空约束 not null
  • 唯一约束 unique 不能重复,但对null不起作用
  • 自增长约束 auto_increment 配合主键使用
  • 外键约束 foreign key
  • 无符号unsigned 不允许添加负数,但会将原来范围为负的加到原来范围为正的上,-128~127变为0-255

添加约束方式1:

create table test(
				username varchar(32) primary key,
				age int
				);

添加约束方式2:

create table test2(
				username varchar(32),
				age int,
				primary key(username)
				);

添加约束方式3:

-- 在修改表时候添加约束
alter table 表名 add primary key(字段名);
-- 删除主键约束 
alter table 表名 drop primary key;

联合主键,将几个字段看作整体,非空且唯一

alter table 表名 add primary key(字段名1,字段名2);

给主键设置自增长

-- 方法和以上类似
create table test3(
				id int auto_increment primary key,
				username varchar(32),
				age int
				);

设置自增长之后,插入数据自动增长序号,
例如:insert into test3 values(null,‘张三’,23);
注意:若你插入进去了一行,假设此时自增长序号为3,然后删除了此行,再先插入了新的一行,新行的自增长序号为4,不是3。

性别约束
如果你有性别约束的需求,mysql可以如下写(利用枚举):

create table test4(
				username varchar(32),
				age int,
				sex enum('男','女','妖')
				);

外键约束

-- orders订单表,users用户表
alter table orders add foreign key (uid) references users (id); 

建表语句如下:

create table user(
id int auto_increment primary key,
username varchar(32),
age int,
sex varchar(1));

create table orders(
idd int auto_increment primary key,
name varchar(32),
price double,
uid int,
foreign key(uid) references user(id));

用来保证数据的有效性和完整性,会在从表一方添加外键约束,去关联主表一方的主键

  • 一旦添加了外键约束,那么两张表之间就会相互制约;
  • 主表不能删除从表还在引用的数据;
  • 从表不能添加主表未存在的数据;

举例:用户张三买了上衣和玫瑰,订单表中有两项,外键1指向用户表主键,表明是张三下的订单。
这样有了外键约束,主表不能删除从表还在引用的数据(张三和李四),但是可以删除王五(从表中没有引用王五),如果要删除张三,那就先删除张三的订单,再删除张三。
从表不能添加主表中未存在的数据(不能在从表中添加一个赵六)。
在这里插入图片描述
级联删除:
只要删除主表中的张三,从表中的张三的订单一并删除。

-- 给订单表增加外键uid 关联用户表主键id,级联删除。
alter table 订单表名  add foreign key (uid) references 用户表名(id) on delete cascade; 

来说说如何删除主键?

alter table test drop primary key;
-- 这样只是删除了唯一性,非空还是没删除所以还得在来让他可以为空。
alter table test change username username varchar(32) null;

删除主键及自增长?

alter table test change id id int; -- 必须先删除自增长才能再删除主键;
alter table test drop primary key;-- 删除限制重复元素;
alter table test change id id int null; -- 删除非空

多表查询:

查询都属于DQL数据查询语言

表一user(id,username,age,sex)
表二orders(idd,name,price,uid)

  • 笛卡尔积查询无意义
select user.id,user.username,orders.* from user,orders;

在这里插入图片描述

  • 隐式内连接(where 后面有多个表名)
select user.id,user.username ,orders.* from user,orders where user.id=orders.uid;

在这里插入图片描述

  • 显式内链接(和隐式内连接查询结果一样,就是语法不同,好像这个相对快速)
select user.*,orders.* from user inner join orders on user.id=orders.uid;

在这里插入图片描述

  • 左外连接
//left关键字左边的表他里面的数据全部展示,left右边的表无对应的数据以null展示
select user.*,orders.* from user left outer join orders on user.id=orders.uid 

在这里插入图片描述

  • 右外连接
  • //right关键字右边的表他里面的数据全部展示,左边的表无对应的数据以null展示
select user.*,orders.* from user right outer join orders on user.id=orders.uid;

在这里插入图片描述

  • 子查询
    一个主查询的条件要依赖与另外一个子查询的结果
-- 若没有外键约束想要查张三的订单,先在user表中根据张三姓名找出张三对应的id,用id当作条件去查询orders表中的订单,现在可以整合在一起了。
select id from user where username="张三";
select * from orders where uid=1;
select * from orders where uid=(select id from user where username="张三");

在这里插入图片描述

  • 自查询
    假设有如下表:employee(员工编号,职位名称,上司编号,薪水);
    现在要查询每个人所对应的上司的名字。
    在这里插入图片描述
select a.username as "员工职位" ,b.username as "上司职位" from employee a,employee b where a.superior=b.empno;

在这里插入图片描述
复制表

-- 将查询的结果作为新表的内容
create table 新表名 as select * from user;
-- 只复制字段,where后写一个假条件。
create table 新表名 as select * from user where false;
create table 新表名 as select * from user where 1=2;
-- 只复制个别字段
create table 新表名 as select 字段名 from user;

取并集
union

select * from user where id=2 union select * from orders where uid=2;

在这里插入图片描述


  • 下来我们说一下数据库对象,就是数据库中数据的载体:表,视图,存储过程,函数,索引

1、存储过程

-- 创建名为mypro的存储过程
delimiter $$
		create procedure mypro()
			begin
				语句
			end $$
delimiter ;
-- 调用存储过程
call mypro();
--  删除存储过程
drop procedure mypro;
-- 查看所有存储过程状态
show procedure status \G;
-- 查看存储过程语句、
show create procedure mypro;
-- 参数类型
in 输入参数
out 输出参数
inout 输入输出参数

举例:

delimiter $$
	create procedure myProcedure1(in id int)
			begin
				select * from user where user.id=id;
			end$$
delimiter ;

调用:

call myProcedure(2);
-- 注意:在命令行下,写存储过程的时候第一行就定一个结束$$标记,并关闭以分号结束,
所以创建成功,调用的时候需要加上以分号结束(delimiter ;)
delimiter $$
create procedure myProcedure2(out str varchar(20))
		begin
			set str='hello';
		end$$
delimiter ;
-- 调用时候接收带回来的值,用一个@代表零时变量。
call myProcedure1(@r);
-- 查看
select @r;

语句

  • if
delimiter $$
create procedure mypro(in num int,out result char(32))
begin
	if num=1 then 
		set result='星期一';
	elseif num =2 then
		set result ='星期二';
	end if;
end$$
delimiter ;
  • while(常用)

declare i int default 1;定义局部变量i,默认值为1;

delimiter $$
create procedure (in num int,out result int)
	begin
		declare i int default  1;
		declare sum  int default 0;
		while(i<=num) do
			set sum=sum+i;
			set i=i+1;
		end while;
	set result=sum;
	end$$
delimiter ;
  • loop(一般不用)
  • repeat(一般不用)

触发器

可以监听增删改三个动作,若有动作,可以向另一张表中记录日志
create trigger 名字 (after/before) (insert/update/delete) on 表名 for each row

-- 创建触发器,监听向user中插入数据,只要插入就在loger(time,log)中记录日志
delimiter $$
	create trigger mytrigger after insert on user for each row
	begin
insert into logger values(now(),"insert succeed!");
end $$
delimiter ;
  • old 和 new
    比如给user中插入数据的时候,给user2表也要添加
delimiter $$
create tigger mytri after insert on user for each row
	begin 
		insert into user2 values(new.id,new.username,new.age,new.age);
	end$$
delimiter ;
-- 更新表
begin
 update user2 set id=new.id,username =new.username,age=new.age,sex=new.sex where id=old.id;
 end$$
 

创建索引
index /key

  • 方式一
-- 给name字段设置索引
create table student(
 id int,
 name varchar(32),
 index(name)
);

  • 方式2
create index myIndex on student(name);
  • 方式3
alter table student add index myIndex(name);

视图

视图就是一张虚拟的表,数据来源与select查出的结果,视图就是封装从表中查出的数据,可理解为给表中数据做了一个镜像。

-- 创建单表视图
create view myView as select * from user;

查询视图:

  • 视图是为了简化查询,而且视图就是用来查询的(只能查询,不能增删改);
  • 可以对外隐藏一些不想让别人看到的数据;
  • 可以封装查询查出的数据;

删除视图:

drop view myView;

修改视图:
视图本身不能修改,但是可以修改视图的数据来源,

alter view myView as select * from user where id=2;

注意: 单表视图可以插入数据,但会影响基表,不建议做增删改;多表不能插入数据。


函数

内置函数和自定义函数

  • 函数一定会有返回值,参数只用来收参数的,不用写in,out;
  • 存储过程没有返回值,out类型又可以起到返回值的作用;

运算符(和Java很像):
除法
x1 div x2;
x1 / x2;
取模:
mod(x1,x2);

内置函数(很多,字符串的方法和数学方法和Java几乎一样)
字符串函数 cancat(str1,str2);
时间函数 now();

自定义函数

delimiter $$
		create function myFun( num int)
		returns int
		begin
			declare i int default 100;
			set i = i+num;
			return i;
		end $$
delimiter ;
-- 调用查看
select myFun(10);

在这里插入图片描述


DCL数据控制语言

权限和安全

-- 给用户名为zhangsan 密码为123456 的用户分配mydb数据库中user表查询和更改的权限。 
grant select ,update on mydb.user to "zhangsan"@"localhost" identified by "123456";
-- 若向要给库中的所有表,并给出全部权限
grant all on mydb.* to "zhangsan"@"localhost" identified by "123456";

在这里插入图片描述


谢谢支持!

猜你喜欢

转载自blog.csdn.net/qq_43371004/article/details/88674071