MySQL学习笔记

这是本人在大二上学期在校学习MySQL时整理的笔记。
如有不足,望指正!欢迎点赞收藏!

一、知识点

SQL语言

概念

结构化查询语言(Stuctured Query Language)简称SQL,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。

特点

主要有7个动词:create、alter、drop、insert、update、delete、select。

SQL语言是一种面向集合的语言,每个命令的操作对象是一个或多个关系,结果也是一个关系。

SQL语言既是自含式语言,又是嵌入式语言。可独立使用,也可嵌入到宿主语言中。

功能

  • 查询(DQL)

    select   where、order by、group by、having
    
  • 操纵(DML)

    insert、update、delete
    
  • 定义(DDL)

    create、drop、alter
    
  • 控制(DCL)

    grant、revoke、commit、rollback、savepoint、declare、cursor、fetch into
    

数据库对象

  • 视图
  • 索引
  • 存储过程
  • 函数
  • 触发器

MySQL数据类型

  • 数值类型(整数类型和小数类型)
  • 字符串类型
  • 日期类型
  • 复合类型(enum和set)
  • 二进制类型

primary和unique的区别

  1. 在一个基本表中只能定义一个primary key约束,但可以定义多个unique约束;
  2. 对于指定的primary key的一个列或多个列的组合,其中任何一个列都不能出现空值,而对于unique所约束的唯一键,则允许为空,但最多只有一个出现null值。
  • 注意:不能把同一列或一组列即定义unique又定义primary。

索引与约束

约束主要用于保证业务逻辑操作数据库时数据的完整性。约束是逻辑层面的概念。

索引是将关键字数据以某种数据结构的方式存储到外存,用于提升数据的检索性能;索引既有逻辑上的概念,更是一种物理存储方式,且事实存在、需要耗费一定的存储空间。

replace和insert的区别

使用replace语句向表中插入新纪录时,如果新记录的主键值或者唯一性约束的字段值与已有记录相同,则已有记录先被删除(注意:已有记录删除时也不能违背外键约束操作),然后再插入新记录

使用replace的最大好处就是可以将delete和insert合二为一,形成一个原子操作,这样就无需将delete操作与insert操作置于事务中了。

drop和delete的区别

delete可以带条件删除,drop不需要

delete和truncate的区别

delete可以带条件删除,truncate不需要;

delete支持事务回滚,truncate不支持。

内连接和外连接的区别

内连接要求满足连接条件的记录才会显示。

外连接中的两张表的关系是不平等的。连接条件只过滤一个表对另一个表不进行过滤(该表中的所有记录出现在结果集中。而在其他属性上填空值NULL)

在这里插入图片描述

where和having的区别

where在分组之前进行限定,如果不满足条件则不参与分组。having在分组之后进行限定,如果不满足结果则不会被查询出来。

where后不可以跟聚合函数,having可以进行聚合函数的判断。

union与union all的区别

使用union时,MySQL会筛选掉select结果集中重复的记录(在结果集合并后会对新产生的结果集进行排序运算,效率稍低)

使用union all时,MySQL会直接合并两个结果集,效率高于union。如果可以确定合并前的两个结果集中不包含重复的记录,建议使用union all

系统会话变量与用户会话变量的区别

共同之处:变量名大小写不敏感

区别:

  1. 系统会话变量以@@开头
  2. 用户会话变量一般以@开头
  3. 系统会话变量无需定义可以直接使用
  4. 用户会话变量无需定义,需要先赋值才可以使用

存储过程和函数的相同点

  1. 在调用时,只需要提供名字以及参数信息
  2. 可以重复使用
  3. 可以增强数据的安全访问控制

存储过程和函数的不同点

  1. 函数仅有一个返回值且必须指定其数据类型;存储过程可以无或一个或多个返回值,返回值需要用out或者inout参数定义

  2. 函数内用select—into为某变量赋值,但不能使用select语句返回结果;存储过程无此限制,甚至可以返回多个结果集

  3. 函数可以嵌入到SQL语句;存储过程一般需要call单独调用

  4. 函数中函数体限制较多;存储过程限制较少

二、数据库

登录

命令行

mysql -u root -p

创建

语法:

create database 数据库名[[default] character set 字符集名][[defalut] collate 字符序名]

例:创建名字为choose的数据库

create database choose;

例:创建名字为hello的数据库,并指定简体中文字符集

create database hello character set gbk;

修改

语法:

alter database 数据库名 character set 字符集

例:

alter database choose character set gbk;

显示结构

show create database 数据库名

例:

show create database choose;

查看

语法:

show databases;

选择当前操作的数据库

语法:

use 数据库名

删除

语法:

drop database[if exists] 数据名

三、表

创建

语法:

create table 表名 (

字段名1 数据类型[约束条件],

字段名2 数据类型[约束条件],

[其他约束条件]

)[engine=存储引擎][default charset=字符集];

例:

create table Department(	
	Departmentidchar(3) primary key,	
	DepartmentNamevarchar(20) NOT NULL unique,	
	DepartmentHeadervarchar(8) NOT NULL,	
	TeacherNum int
);

例:创建学生表(学号,姓名,性别,专业号,出生日期,班长)

use choose;
create table student(	
	sno int unsigned,	
	name varchar(8),	
	sex char(2),	
	spec char(20),	
	birth date,	
	level int unsigned
);

例:创建个人信息表(姓名、性别、爱好,使用集合和枚举类型)

use choose;
create table person(	
xmvarchar(8),	
xbenum('男','女'),	
xqset ('电影','旅游','游戏','音乐','运动','购物')
);

查看

查看当前数据库中所有的表

show tables

查看指定表结构

desc 表名

查看指定表的详细信息

show create table 表名

复制

方法一:复制表结构

create table 新表名 like 原表

方法二:复制表结构及原数据

create table 新表名 select * from 原表

修改

添加新字段

alter table 表名 add 新字段名 新数据类型[新约束条件][first|after 旧字段名]

修改字段名

  1. 修改表的字段名(及数据类型)

    alter table 表名 change 旧字段名 新字段名 新数据类型

  2. 如果仅对字段的数据类型进行修改

    alter table 表名 modify 字段名 新数据类型

添加约束条件

alter table 表名 add constraint 约束名 约束类型(字段名)

删除约束条件

  1. 删除主键

    alter table 表名 drop primary key

  2. 删除外键,需指定外键约束名称

    alter table 表名 drop foreign key 约束名

  3. 若要删除表字段的唯一性约束,实际只需删除该字段的唯一性索引即可

    alter table 表名 drop index 唯一索引名

  4. 其他

    alter table 表名 engine=新的存储引擎类型

    alter table 表名 default charset=新的字符集

    alter table 表名 auto_increment=新的初始值

    alter table 表名 pack_keys=新的压缩类型

修改表名

rename table 旧表名 to 新表名;

alter table 旧表名 rename 新表名;

删除

删除指定表

drop table 表名

删除字段

alter table 表名 drop 字段名

索引

种类:

* 主索引、聚簇索引* 唯一性索引* 普通索引* 符合索引* 全文索引

创建索引

方法一

create table 表名(    
	字段名1 数据类型[约束条件],   
	...[其他约束条件],   
	...[ unique | fulltext]  index[索引名] ( 字段名[(长度)]  [ asc| desc] )
)engine=存储引擎类型default charset=字符集类型

例:

create table book(
    isbnchar(20) primary key,
    name char(100) not null,
    brief_introductiontext not null,
    price decimal(6,2),
    publish_timedate not null,
    unique index isbn_unique(isbn),
    index name_index(name (20)),
    fulltextindex brief_fulltext(name,brief_introduction),
    index complex_index(price,publish_time)
) engine=MyISAMdefault charset=gbk

方法二:在已有表上创建索引

create [ unique | fulltext] index 索引名 on 表名( 字段名[(长度)] [ asc| desc] )

alter table 表名 add [ unique | fulltext] index索引名( 字段名[(长度)] [ asc| desc] )

删除索引

drop index 索引名 on 表名

四、记录

插入

insert into 表名[(列名,列名)] values(值列表)

  • 注意:
    1. 向自增型auto_increment字段插入数据时,建议插入null值
    2. 外键字段不能输入空值、默认值、父表没有的数据

在插入数据前设置字符集

set chatacter_set_client = 字符集名字

use choose;
set character_set_client=gbk; 
insert into classes values(null,'2012自动化4班', '机电工程');
select * from classes;

批量插入多条记录

insert into 表名[(字段列表)] values

(值列表1),

(值列表2),

(值列表n);

例:向student表中插入多条数据

INSERT INTO student VALUES
('1414855308','马琦','13980569900',1),
('1414855328','刘梅红','13688500900',2),
('1414855406','王松','13680500900',3),
('1416855305','聂鹏飞','13680500900',1),
('1418855212','李冬旭','15888050090',4),
('1418855232','王琴雪','15580500900',4);

使用insert… select插入结果

insert into 目标表名[(字段列表1)]

select (字段列表2) from 原表 where 条件表达式

例:创建一个学生表,它与student表的结构相同,然后将student表中的所有记录插入新建的学生表中

use choose;
create table new_student like student;
insert into new_student select * from student;
select * from new_student;

使用replace插入新纪录

语法格式1:

replace into 表名[(字段列表)] values (值列表)

语法格式2:

replace [into] 目标表名[(字段列表1)]

select (字段列表2) from 原表 where 条件表达式

语法格式3:

replace [into] 表名 set 字段1=值1,字段2=值2

例:replace用向学生表插入数据

replace into student values ('2012001', '张三丰','15044500900',1);

查询

单表查询

select [distinct] 列名列表

字段列表

from 数据源

[where 条件]

[group by 分组字段[having条件表达式]]

[order by 排序字段[asc|desc]]

[limit [m,]n];

  • group by:对查询结果按指定列的值分组,该属性列值相等的元组为一个组。通常会在每组中作用集函数
  • having:筛选出只有满足指定条件的组
  • order by:对查询结果表按执行列值的升序或降序排序DISTINCT则可以清除重复的行
  • limit [start,] length:限制输出结果的行数。start表示从第几行记录开始检索,length表示检索多少行记录。表中第一行记录的start值为0

例:检索choose表从第2条开始的3条记录

select * from choose limit 1, 3;
where

使用逻辑运算符

  1. 逻辑非(!)的使用

    例:检索课程上线不是60人的所有课程信息

    select * from course where !(up_limit=60);
    select * from course where up_limit != 60;
    select * from course where up_limit <> 60;
    
  2. 逻辑与and的使用

    例:检索数据库课程不及格的学生

    select studentid,courseid,gradefrom gradewhere courseid='Dp010003' and grade<60;
    
  3. 取值范围(下届-上界)的使用

    1. between…and…

      select student_no, score from choose where score  between 85 and 100;
      
    2. >= <=

      select student_no, score from choose where score>=85 and  score<=100;
      
  4. 逻辑或or的使用

    例:检索所有姓张和姓田的学生

    select * from student where student_name like '张%' or student_name like '田%';
    
  5. in运算符的使用

    例:检索所有姓张和姓田的学生

    select * from student where substring(student_name,1,1) in('张','田');
    

使用like进行模糊查询

通配符含义举例说明
%零个或多个任意字符串like '好%'表示以"好"开头的文字
_任意单个字符like ‘_rt’ 表示所有以 “rt”结尾的三个字母

where子句设置结果集的过滤条件

查询条件运算符
比较=, <=, >=, <>, >, <, !=, !>, !<
范围between…and…, not between…and…
集合in,not in
空值is NULL,isnot NULL
字符匹配like, not like
多重条件and, or, !
order by

select

order by 字段名1 [asc|desc] […,字段名n [asc|desc]]

多列排序规则:当order by子句指定了多个排序列时,系统先按照子句中第一列的顺序排列,当该列出现相同值时,再按照第二列的顺序排列,依次类推。

例:按降序查询学生分数

select * from choose order by score desc;
聚合函数

常用的有5个:

  • count()

    • 注意:排除了null值

    • 解决方案:

      1. 选择不包含空的列进行计算

      2. 可用ifnull(列名, 0),把null当做是0来操作

  • avg()

  • sum()

  • max()

  • min()

group by

group by 字段列表 [having 条件表达式] [with rollup]

  • group by:将结果集分为若干个组
  • 聚合函数:对每个组内的数据进行信息统计
  • with rollup:对每个组进行汇总运算

group by子句将查询结果按照某个字段(或多个字段)进行分组(字段值相同的记录作为一个分组)

例:统计每一个班的学生人数

select count(*), class_no from student group by class_no;

例:按照性别分组,分别查询男、女同学的人数和平均分

select sex, count(id), avg(math) from student group by sex;

例:按照性别分组,分别查询男、女同学的人数和平均分。要求:分数低于70分的人不参与分组,分组后人数要大于2个人

select 
	sex, avg(math) count(id) 
from 
	student 
where 
	math > 70 
group by 
	sex 
having 
	count(id) > 2;
having

用于设置分组或聚合函数的过滤筛选条件

例:检索平均成绩高于70分的学生信息及平均成绩

select 
	ch.student_no, student_name, avg(score) 
from 
	choose ch 
join 
	student st 
on 
	ch.student_no = st.student_no 
group by 
	ch.student_no 
having 
	avg(score) > 70;

小结:

查询语句执行顺序:先用where子句过滤不符合条件的数据记录,接着用group by子句对余下的数据记录进行分类汇总,最后再用having子句排除不符合条件的组。

多表查询

多张数据库表”拼接”成一个结果集时,需要制定“拼接”条件,该“缝补”条件称为连接条件

方法1:from 表1[连接类型] join 表2 on 条件

方法2:from 表1,表2 where 条件

  • 方法2不是规范方法

连接类型:

  • inner(内连接)
  • left(左外连接,简称左连接)
  • right(右外连接,简称右链接)

student表

student_nostudent_namestudent_contactclass_no
2012001张三150000000001
2012002李四160000000001
2012003王五170000000003
2012004马六180000000002
2012005田七190000000002

class表

class_noclass_namedepartment_name
12012自动化1班机电工程
22012自动化2班机电工程
32012自动化3班机电工程

内连接

参与连接的表时平等关系,会从两个表中提取满足条件的记录并组合成新的记录。

select 列表列名 from 表1 [inner] join 表2 on 连接条件

例:

select 
	student.*, class_name, department_name 
from 
	student 
join 
	classes 
on 
	student.class_no = classes.class_no;

外连接

与内连接不同,外连接只过滤一个表,对另一个表不进行过滤(该表的所有记录出现在结果集中)

from 表1 left join 表2 on 表1和表2之间的连接条件

from 表1 right join 表2 on 表1和表2之间的连接条件

  • 表1左连接表2,意味着查询结果集中需包含表1的全部记录,然后表1按指定的连接条件与表2进行连接,若表2中没有满足连接条件的记录,则结果集中表2相应的字段填入NULL。

  • 右连接同理

例:

select 
	student.*, class_name, department_name 
from 
	student 
left join 
	classes 
on 
	student.class_no = classes.class_no;

多表连接

方法1:

from 表1,表2,表3 where 表1和表2之间的连接条件 and 表2和表3之间的连接条件

方法2:

from 表1

[连接类型] join 表2 on 表1和表2之间的连接条件

[连接类型] join 表3 on 表2和表3之间的连接条件

在这里插入图片描述

例:检索数据库课程不及格的学生

select 
	student.student_no, student_name, course_name, score 
from 
	course 
join 
	choose 
on 
	course.course_no = choose.course_no 
join 
	student 
on 
	student.student_no = choose.student_no 
where 
	course_name like '%数据库%' and score<60;

联合及嵌套查询

使用union可以将多个select语句的查询结果集组合成一个结果集。

select 字段列表1 from table1

union [all]

select 字段列表2 from table2

  • 字段列表1与字段列表2的字段个数必须相同,且具有相同的数据类型。合并产生的新结果集的字段名与字段列表1中的字段名对应

例:检索所有的学生及教师的信息

select 
	student_no 编号, student_name 姓名, student_contact 电话 
from 
	student 
union select 
	teacher_no, teacher_name, teacher_contact 
from 
	teacher;

在这里插入图片描述

修改

update 表名

set 字段名1=值1,字段名2=值2,…,字段名n=值n

[where 条件表达式]

例:将classes表中班级号小于等于3的院系名改为“机电工程学院”

update classes set depetment_name='机电工程学院' where class_no<=3;

例:将课程表中每门课程的课程上限人数增加10人

update course set up_limit=up_limit+10;

删除

delete from 表名 [where 条件表达式]

例:删除“2012计算机应用1班”班的学生信息

use choose;
delete from student where class_name='2012计算机应用1班';

例:删除所有的班级表的信息。

delete from classes;

truncate [table] 表名

例:清空学生表

use choose;
truncate student;

五、约束

  • 主键约束(primary key)
  • 非空约束(not NULL)
  • 默认值约束(default)
  • 唯一性约束(unique)
  • 外键约束(foreign key)
  • 检查约束(check)(借助触发器或符合类型实现)

主键约束primary key

primary key约束用于定义基本表的主键,起唯一标识作用,并且其值不能为NULL,以此来保证实体的完整性。

例:

use choose;
create table student(	
	student_no char(11) primary key,	
	student_name char(10) not null,	
	student_sex char(2),	
	student_contact char(20) not null,	
	student_birth date,class_noint
);

例:在choose数据库中创建班级表(班号,班名,系号),并将系号、班号组合设置为主键。

use choose;
create table classes(	
	class_noint,	
	class_name char(10) unique,
	dept int,	
	primary key (dept, class_no)
);

非空约束not NULL

要求某个字段取值不能为空。

默认值约束default

向表中插入记录时,如果没有指定某个字段的取值,该字段则采用默认值插入。

status char(6) default "未审核"

唯一性约束unique

用于表名基本表在某一列或多个列的组合上的取值唯一。

class_name char(20) not null unique

注意:主键自带为空和唯一特性,不需要单独声明,非主键但是具有唯一值的用unique

例:在choose数据库中创建班级表(班号,班名,系号),并将班号设置为主键。

use choose;create table classes(	class_no int primary key ,	class_name char(10) unique, dept int);

外键约束foreign key

外键约束用于有关联的两个或多个表。通过使用主键和外键(或唯一值)之间的关系,使表中的键值在相关表中保持一致。

语法:

constraint 约束名 foreign key(子表字段名) references 外表名(主表字段名) [on delete 级联选项] [on update 级联选项]

例:

constraint st_cl_fk foreign key (class_no) references classes (class_no)

例:将学生表的班号设为外键,参照班级表的班号

use choose;
create table student(    
	student_no char(11) primary key,
	student_name char(10) not null,    
	student_sex char(2),    
	student_contact char(20) not null,    
	student_birth date,    
	class_no int,    
	constraint st_cl_fk foreign key (class_no) references classes(class_no)
);

自增型字段auto_increment

优点:

  1. 自动编号,速度快,按顺序存放,有利于检索
  2. 数字型,占用空间小,易排序,在程序中传递也方便
  3. 如果通过非系统增加记录时,可以不用指定该字段,不用担心主键重复问题。

例:建班级表(班号,班名,系号),班号为主键且自增型

use choose;
create table classes(    
	class_no int auto_increment primary key,    
	class_name char(10) unique,
	dept int
);

六、视图

视图是数据库对象之一,视图中保存的仅是一条select语句(虚表)。即将多个基本表(或视图)中的数据通过视图动态的组织在一起,像普通表一样使用

创建

create view 视图名(视图字段列表)

as select 语句

with [local|cascaded] check option

查看

show tables like ‘view%’;

show create view 视图名;

desc 视图名;

删除

drop view 视图名;

七、数据库编程

1.变量

  • 系统变量(必须在前加@@

    • 全局变量

      在启动时服务自动初始化

    • 会话变量

      建立新连接时。会其修改只会影响到当前的会话也就是当前的数据库连接

    例如:

    -- 获得现在使用的MySQL版本
    select @@version;
    -- 获得系统当前时间,这个可以不用@@
    select current_time;
    -- 设置会话变量sql_select_limit的值设置为50
    set @@session.sql_select_limit = 50;
    
  • 用户变量(用前必须定义和初始化

    • 会话变量

      其名称前加@,定义和初始化可直接用set或select

    • 局部变量

      用户函数或存储过程等程序中,定义和初始化可直接用declare和set或select赋值

      -- 创建用户变量name1并赋值为“王林”
      set @name = '王林';
      -- 创建用户变量user1并赋值为1,user2赋值为2,user3赋值为3
      set @user1=1, @user2=2, @user3=3;
      -- 查询用户变量
      select @name, @user1, @user2, @user3
      -- 使用查询结果给变量赋值
      set @studentid=(select studentid from student where studentname='张宏');
      select studentname into @studentname from student where studentid='st0109010002';
      select studentname,studentid into @sname1,@sid1 from student where studentid=@studentid;
      -- 将用户变量用于查询
      select * from grade where StudentID = @studentid;
      -- 用select语句将表中数据赋值给变量
      select @mg = max(grade) from grade;
      -- 查询用户变量
      select @studentid, @mg;
    

    在这里插入图片描述

运算符

运算符含义
=等于
>大于
<小于
>=大于等于
<=小于等于
<>、!=不等于
<==>相等或都等于空
is null是否为NULL
between…and…是否在区间内
in是否在集合内
like模式匹配
regexp正则表达式模式匹配
not或!逻辑非
and或&&逻辑与
or或||逻辑或
xor逻辑异或
&按位与
|按位或
^按位异或
~按位取反
>>位右移
<<位左移

2.系统函数

数学函数

字符串函数

函数名作用举例
LEFT获取左边字符串select left(‘赵钱孙李’,3)
RIGHT截取右边字符串select right(‘赵钱孙李’,3)
LOWER转换为小写字符串select lower(‘ABCDEFG’)
UPPER转换为大写字符串select upper(‘abcdefg’)
REVERSE反序字符串select reverse(‘赵钱孙李’)
LENGTH获取字符串长度select length(‘天下之大,无奇不有’)
REPEAT重复生成字符串select repeat (‘hello’,5)
RTRIM清除右边空格select rtrim('123456789 ')
POSITOIN字符所在位置select position(‘l’ in ‘hello’);
CONCAT连接字符串select concat(‘My’,’_’,‘SQL’);

例如:

-- 查找学生表家庭住址的前三个字符
select left(HomeAddr, 3) from student;
-- 将教师的姓名,性别和职称连接
select concat(Teachername, Sex, Profession) from teacher;
-- 查询学生姓名的长度
select length(StudentName) from student;

条件控制函数

函数名函数作用
if(条件,v1,v2)条件为真返回v1,否则v2
ifnull(v1,v2)如果v1为null,返回v2
nullif(v1,v2)如果v1等于v2,返回null,否则返回v1
case …when… then …else default条件与when中值相等,则返回then对应的结果,否则返回default

例如:

-- 根据分数显示成绩等级
set @score1=40, @score2=77;
select if(@score1 >= 60, '及格', '不及格') 数学成绩, if(@socre2>=60, '及格', '不及格') 语文成绩;
-- 根据分数显示成绩等级
select ifnull(@score1, '没有成绩') 成绩;
-- 转换今天的星期值
set @t=now(), @week_no=weekday(@t);
set @week=case @week_no
when 0 then '星期一'
when 1 then '星期二'
when 2 then '星期三'
when 3 then '星期四'
when 4 then '星期五'
else '周末'
end;
select @t,@week_no,@week

系统信息函数

日期时间函数

其他函数

-- found_rows():返回最后一个select查询的进行检索的总行数
select found_rows();
-- cast():将一个值转换为指定的数据类型
select cast(now() as char);

3.自定义函数创建

create function 函数名(参数1,参数2,…)

returns 数据类型

[函数选项]

begin

​ 函数体;

return 语句;

end;

注意:

  • 参数和java语法不同,例如是(x smallint),而非(smallint x)

  • 函数选项:

    • no sql
    • reads sql data
  • 函数里变量的定义:declare 变量名 类型;

  • 建议函数名前加fn_前缀,以示区分

例如

-- 创建一个名为fn_addTwoNumber()的函数
use xkgl;
delimiter $$
create function fn_addTwoNumber(x smallint, y smallint)
returns smallint
no sql
begin
	return x+y;
end$$

-- 创建函数fn_get_name(),根据学生学号查询姓名
delimiter $$
create function fn_get_name(no char(12))
returns char(20)
reads sql data
begin
	declare name char(20);
	select studentname into name from student where studentid=no;
	if isnull(name) then set name="无此人";
	end if
	return name;
end$$

4.自定义函数管理

查看

查看当前数据库中所有的自定义函数信息

show function status;

模糊查询自定义函数

show function status like 模式

show function status like 'fn_get%';

查看指定函数详细信息

show create function fn_get_name;

删除

drop function 函数名

drop function get_name_in;

5.条件语句

if…else

if 条件表达式1 then 语句块1;

[elseif 条件表达式2 then 语句块2]…

[else 语句块n]

end if;

  • 注意:end if后必须以;结束

例如:

-- 创建函数get_name1,使该函数根据学生学号或者教师工号返回他们的姓名信息
delimiter $$
create function fn_get_name1(no char(20), role char(20))
returns char(20)
begin
	declare name char(20);
	if (role='student') then
		select studentname into name from student where studentid=no;
	elseif(role='teacher') then
		select teachername into name from teacher where teacherid=no;
	else set name='输入有误!';
	end if;
	if isnull(name) then set name='无此人';
	end if;
	return name;
end$$

case

分为简单case和搜索case

case 条件

when 条件值 then 操作;

[when 条件值 then 操作;]

[else 操作;]

end case;

case

when 条件 then 操作;

[when 条件 then 操作;]

[else 操作;]

end case;

  • 注意:end case后必须以;结束

例如:

delimiter $$
create function fn_get_week(week_noint) returns char(20)
no sql
begin 
	declare week char(20);
	case week_no 
	when 0 then set week='星期一';
	when 1 then set week='星期二';
	when 2 then set week='星期三';
	when 3 then set week='星期四';
	when 4 then set week='星期五';
	else set week='周末'; 
	end case;
	return week;
end$$

6.循环语句

有三种循环语句,whilerepeatloop

while

[循环标签:]while 条件表达式 do

循环体;

end while[循环标签];

-- 创建函数get_sum实现1到n的累加运算
DELIMITER $$
CREATE FUNCTION fn_get_sum(n INT)
RETURNS INT
NO SQL
BEGIN
	DECLARE start_, sum_ INT;
	SET start_=1, sum_=0;
	WHILE start_ <= n DO
	SET sum_ = start_ + sum_;
	SET start_ = start_ + 1;
	END WHILE;
	RETURN sum_;
END$$

-- 创建函数get_sum1实现1到n的累加运算,n大于100也只算到100
delimiter $$
create function fn_get_sum1(n int) returns int 
no sql
begin
	declare start, sum int default 0;
	addnum: while start<n do 
    set start = start + 1;
    set sum = sum + start;
    if (start =100) then leave addnum;
    end if;
    end while addnum;
    return sum;
end$$

-- 创建函数get_sum2实现1到n的奇数累加运算
delimiter $$
create function fn_get_sum2(n int) returns int 
no sql
begin
	declare start, sum intdefault 0;
	addnum: while start<n DO
        set start = start + 1;
        if (start % 2)=0 then iterate addnum;
        end if;
        set sum=sum+start;
	end while addnum;
	returnsum;
end$$


repeat

[循环标签:]repeat

循环体;

until 条件表达式

end repeat [循环标签];

其实就是do while

-- 创建函数get_sum3实现1到n的累加运算
delimiter $$
create function fn_get_sum3(n int) returns int
no sql
begin
    declare start, sum intdefault 0;
    repeat
        set start = start + 1;
        set sum=sum+start;
        until start=n
    end repeat; 
    return sum;
end$$

loop

[循环标签:] loop

循环体;

if 条件表达式 then

leave [循环标签];

end if;

end loop;

-- 创建函数get_sum4实现1到n的累加运算。
delimiter $$
create function fn_get_sum4(n int) returns int
no sql
begin
    declare start,sum int default 0;
    addnum: loop 
    set start = start + 1;
    set sum=sum+start;
    if start=n then leave addnum;
    end if;
    end loop;
    return sum;
end
$$

在这里插入图片描述

7.存储过程创建

存储过程(Stored procedure)是在数据库中定义的一些完成特定功能的SQL语句集合,经编译后存储在数据库中。

优点:

  1. 存储过程能实现较快的执行速度
  2. 存储过程能够减少网络流量
  3. 存储过程可被作为一种安全机制来充分利用

create procedure 存储过程名(参数1,参数2,…)

[存储过程选项]

begin

​ 存储过程语句块;

end;

  • 必须说明参数类型([in|out|inout])和参数的数据类型(char, int)

    • 例如 in a1 int, out a2 char(6)
  • 建议过程名前加pr_前缀

  • 存储过程选项:no sql, reads sql data, modifies sql data

  • 变量的定义:declare 变量

例:创建名为get_num的存储过程,根据学号统计选修课程数输出保存到变量中

delimiter $$
create procedure pr_get_num(in st_no1 char(12),out ch_num1 int)
reads sql data
begin
select count(*) into ch_num1 from grade where studentid=st_no1;
end$$

例:创建名为count_dsn的存储过程,根据系号,统计不同系的学生人数。

delimiter $$
create procedure pr_count_dsn1(in did char(10))
reads sql data
begin 
select departmentid系名,count(*) 人数
from class join student on student.classid=class.classid
where departmentid=did;
end$$

调用:

CALL 存储过程名([参数[,…]])

例:调用存储过程pr_get_num(in st_no1 char(12),out ch_num1 int)

set @st_no1 = 'St0109010002';
set @ch_num1 = 0;
call pr_get_num(@st_no1, @ch_num1);
select @ch_num1;

call pr_get_num('St0109010002', @count);
select @count;

例:调用存储过程pr_count_dsn(in did char(10))

call pr_count_dsn('dp01');
-- 完整版
delimiter $$
create procedure pr_get_num(in st_no1 char(12),out ch_num1 int)
reads sql data
begin 
select count(*) into ch_num1 from grade where studentid=st_no1;
end$$

set @st_no1='st0109010002';
set @st_num=0;
call pr_get_num(@st_no1,@st_num);
select @st_num;

8.存储过程管理

查看

查看存储过程的状态

show procedure status like ‘pr%’;

查看存储过程的定义

show create procedure pr_get_num;

show create procedure pr_get_num\G

删除

drop procedure [endexits] 名字

9.触发器

触发器是数据库对象之一,实在对表进行操作时自动执行的一段SQL程序(类似存储过程或函数)。

特点:

  1. 针对特定的表
  2. 不能接受和传递参数
  3. 不能手工调用执行,而是由插入、更新和删除时间触发执行

八、数据库设计

数据库设计阶段

  1. 需求分析
  2. 概念设计
  3. 逻辑结构设计
  4. 物理设计
  5. 实施
  6. 运行和维护

ER模型设计

概念设计(E-R图的设计):

将收集到的数据进行分类和全局性描述,建立实体、实体属性和实体间的联系

  • E-R图由实体属性联系三个要素构成

实体

实体(Entity)是具有公共性质的可相互区别的现实世界对象的集合。用**矩形框**表示。实体中每个具体的记录值被称为实例。

在这里插入图片描述

属性

属性(Attribute)是实体所具有的某一特征或性质。一个实体的属性多少由用户的信息需求决定,属性在E-R图中用椭圆表示。能唯一标识实体的属性被称为码(Key)。

在这里插入图片描述

联系

关系(Relation)表示实体间存在的联系或对应关系,用菱形表示,菱形框内写明联系名,同时在无向边旁标上联系的类型(1:1, 1:n或m:n),联系也可以有属性

在这里插入图片描述

三个实体型之间联系示例
在这里插入图片描述在这里插入图片描述在这里插入图片描述

九、事务

概念:如果一个包含多个步骤的业务操作被事务管理,那么这些操作要么同时成功,要么同时失败。

四大特征:原子性、持久性、隔离性、一致性。

开启、回滚、提交

开启事务

start transaction

回滚

rollback

提交

commit

CREATE TABLE ACCOUNT(
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(10),
	balance DOUBLE
);

INSERT INTO ACCOUNT (NAME, balance) VALUES ("zhangsan",1000), ("lisi",1000);

SELECT * FROM ACCOUNT;

UPDATE ACCOUNT SET balance = 1000;

-- 张三给李四转账500元

-- 0.开启事务
START TRANSACTION;
-- 1.张三账户-500
UPDATE ACCOUNT SET balance = balance -500 WHERE NAME = 'zhangsan';
-- 2.李四账户+500
UPDATE ACCOUNT SET balance = balance +500 WHERE NAME = 'lisi';
-- 发现执行没有问题,提交事务
COMMIT;
-- 发现出问题了,回滚事务
ROLLBACK;

事务提交的两种方式:

  1. 自动提交
    • MySQL自动提交
    • 一条DML(增删改)语句会自动提交一次事务
  2. 手动提交
    • Oracle默认手动提交事务
    • 需要开启事务,再提交

修改事务的默认提交方式:

  • 查看事务的默认提交方式

    select @@autocommit; -- 1 代表自动提交  0 代表手动提交
    
  • 修改默认提交方式

    set @@autocommit = 0;
    

事务的隔离级别

概念:多个事务之间是隔离的,相互独立的。但是如果多个事务操作同一批数据则会引发一些问题,设置不同的隔离级别就可以解决这些问题。

存在问题:

  1. 脏读:一个事物读取到另一个事务中没有提交的数据。
  2. 不可重复读(虚读):在同一个事务中,两次读取到的数据不一样。
  3. 幻读:一个事物操作(DML)数据表中所有记录,另一个事务添加了一条数据,则第一个事务查询不到自己的修改。
  • 隔离级别:

    1. read uncommitted:读未提交

      • 产生的问题:脏读、不可重复读、幻读
    2. read committed:读已提交(Oracle)

      • 产生的问题:不可重复读、幻读
    3. repeatable read:课重复读(MySQL默认)

      • 产生的问题:幻读
    4. serializable:串行化

      • 可以解决所有的问题
  • 注意:隔离级别从小到大安全性越来越高,但是效率越来越低

  • 数据库查询隔离级别:

    select @@tx_isolation;
    
  • 数据库设置隔离级别:

    set global transaction isolation level 级别字符串
    
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值