MySQL数据库基础

视频课链接1:047-MySQL-关联关系-一对多、多对一_哔哩哔哩_bilibili047-MySQL-关联关系-一对多、多对一是千锋教育MySQL数据库教程,mysql安装到mysql高级一套通关的第49集视频,该合集共计110集,视频收藏或关注UP主,及时了解更多相关视频内容。icon-default.png?t=N7T8https://www.bilibili.com/video/BV1qb4y1Y722?p=49&spm_id_from=pageDriver&vd_source=409c279a570617f1f63ce4ae8695f69f

视频课链接2:51. 基础-事务-简介_哔哩哔哩_bilibili51. 基础-事务-简介是黑马程序员 MySQL数据库入门到精通,从mysql安装到mysql高级、mysql优化全囊括的第51集视频,该合集共计195集,视频收藏或关注UP主,及时了解更多相关视频内容。icon-default.png?t=N7T8https://www.bilibili.com/video/BV1Kr4y1i7ru?p=51&vd_source=409c279a570617f1f63ce4ae8695f69f

一. 数据库介绍

1. 关系型数据库与非关系型数据库

关系型数据库:采用了关系模型来组织数据存储,以表格的形式存储数据并记录数据之间的关系,可以建立表格间的关联来维护数据和数据间的关系。

非关系型数据库:采用键值对的模型来存储数据,不记录数据间的关系。在非关系型数据库中基于特定的存储结构来解决一些大数据应用的难题。常用NoSQL(Not only SQL)数据库来指代非关系型数据库。

2. 常见的数据库

关系型数据库:

MySQL,PostgreSQL,Oracle,SQL Server,Access,达梦数据库

非关系型数据库:

i)面向检索的列式存储 Column-Oriented:HaBase

ii)面向高并发的缓存存储 Key-Value:Redis

iii)面向海量数据访问的文档存储 Document-Oriented:MongoDB

3. SQL语句分类
  1. DDL Data Definition Language 数据定义语言(用于对数据库对象(数据库、数据表、视图、索引等)的CRUD)
  2. DML Data Manipulation Language 数据操作语言(用于对数据表中数据的CRUD)
  3. DQL Data Query Language 数据查询语言
  4. DCL Data Control Language 数据控制语言(用于事务管理的控制性语句)

SQL指令不区分大小写,每条指令以分号结束。

二. DDL

1. 创建、查询、修改、删除、使用(切换)数据库

查询、创建数据库

修改、删除、使用(切换)数据库

MySQL数据库基础_第1张图片

2. 创建、查询、删除、修改数据表

创建数据表

MySQL数据库基础_第2张图片

查询、删除数据表

MySQL数据库基础_第3张图片

修改数据表

MySQL数据库基础_第4张图片

三. MySQL数据类型

1. 数值类型

类型

内存空间大小

范围

说明

tinyint

1byte

有符号 -128~127

无符号 0~255

特小型整数(年龄)

smallint

2byte

有符号 -32768~32767

无符号 0~65535

小型整数

mediumint

3byte

有符号 -2^31~2^31-1

无符号 0~2^32-1

中型整数

int/integer

4byte

整数

bigint

8byte

大型整数

float

4byte

单精度

double

8byte

双精度

decimal

第一个参数+2

decimal(10,2)表示数值一共有10位,小数有2位

不包括小数点

2. 字符类型

类型

字符长度

说明

char

0~255字节

定长字符串,最多可以存储255个字符,当我们指定char(n)时,最多存n个字符,如果添加的数据少于n,则补'\u0000'至n长度

varchar

0~65536字节

可变长度字符串

tinyblob

0~255

存储二进制字符串

blob

0~65535

同上

mediumblob

0~1677215

同上

longblob

0~4294967295

同上

tinytext

0~255

文本数据(字符串)

text

0~65535

同上

mediumtext

0~1677215

同上

longtext

0~4294967295

同上

3. 日期类型

类型

格式

说明

date

2023-10-29

日期,只存储年月日

time

11:12:13

时间,只存储时分秒

year

2023

年份

datetime

2023-10-29 11:12:13

日期+时间

timestamp

20231029111213

时间戳

四. 字段约束

在创建数据表的时候,对数据表的列的数据限制性的要求(对标的列中的数据进行限制),以确保数据的有效性、完整性、正确性。

1. 非空约束not null

MySQL数据库基础_第5张图片

2. 唯一约束unique

MySQL数据库基础_第6张图片

3. 主键约束primary key

主键就是数据表中记录的唯一标识,一张表中最多只能有一个主键(主键可以是一列,也可以是多个列的组合,即联合主键)

MySQL数据库基础_第7张图片

4. 主键自动增长auto_increment

在创建一张数据表时,如果没有合适的列作为主键时,可以额外定义一个与记录无关的列(ID)做主键,无具体含义,仅作唯一标识。int型,自动增长。

MySQL数据库基础_第8张图片

保证唯一性,但不保证连续性。例如有三条信息后,先删除第三条再添加第四条,ID会分别为1,2,4。

5. 联合主键primary key()

不能像定义单个主键那样在后面加上关键字,否则会有多个主键,而不是唯一的。

MySQL数据库基础_第9张图片

五. DML

1. 插入数据insert

MySQL数据库基础_第10张图片

2. 删除数据delete

MySQL数据库基础_第11张图片

3. 修改数据update(set)

MySQL数据库基础_第12张图片

六. DQL

1. 查询基础语法select(from、union)

MySQL数据库基础_第13张图片

多条查询语句可以用UNION连接,即是把这些联合成一条查询结果

MySQL数据库基础_第14张图片

2. where子句

在删除、修改及查询的语句后都可以添加where子句(条件),用于筛选。

MySQL数据库基础_第15张图片

MySQL数据库基础_第16张图片

3. like子句

在where子句的条件中,可以使用like关键字来实现模糊查询。

MySQL数据库基础_第17张图片

4. 查询结果处理(计算列、as起别名、distinct)

设置查询的列、计算列

MySQL数据库基础_第18张图片

as起字段别名

MySQL数据库基础_第19张图片

distinct消除重复行

MySQL数据库基础_第20张图片

5. 排序oreder by

将查询到的满足条件的记录按指定的列的值升序/降序排列

asc升序(默认),desc降序

MySQL数据库基础_第21张图片

6. 聚合函数

SQL中提供了一些可以对查询记录的列进行计算的函数——聚合函数

count()统计个数,max()最大值,min()最小值,sum()求和,avg()求平均值

MySQL数据库基础_第22张图片

7. 日期函数、字符串函数

i)日期函数:

在向日期类型的列添加数据时,可以用yyyy-mm-dd hh:mm:ss格式的字符串来赋值

now()获取当前时间,sysdate()系统当前时间

MySQL数据库基础_第23张图片

ii)字符串函数:

通过SQL指令对字符串进行处理

concat()拼接,upper()转换为大写输出,lower()转换为小写输出,substring(column,start,len)获取子串,start从1开始

MySQL数据库基础_第24张图片

8. 分组查询group by(having)

分组——就是将数据表中的记录按照指定的类进行分组

语句执行顺序:①先根据where条件从数据库查询记录,②group by对查询记录进行分组,③执行having对分组后的数据进行筛选。

MySQL数据库基础_第25张图片

MySQL数据库基础_第26张图片

having关键字

MySQL数据库基础_第27张图片

9. 分页查询limit

MySQL数据库基础_第28张图片

limit(param1,param2):

param1 int,表示查询语句中的第一条数据索引(索引从0开始

param2 int,便是查询的条数(若剩下的数据小于param2,只返回剩下的所有记录)

MySQL数据库基础_第29张图片

七. 数据表的关联关系

1. 一对一关联

人--身份证,学生--学籍,用户--用户详情

方案一:主键关联——两张数据表中主键相同的数据,互为相互对应的数据

MySQL数据库基础_第30张图片

方案二:唯一外键关联——在任意一张表中添加有唯一约束的外键约束,与另一张表主键关联

MySQL数据库基础_第31张图片

2. 一对多、多对一

一对多:班级--学生

多对一:学生--班级

方案:在多的一端添加外键,与一的一端主键进行关联

MySQL数据库基础_第32张图片

3. 多对多关联

学生--课程,会员--社团

方案:额外创建一张关联关系表——在关系表中定义两个外键分别与两个数据表的主键进行关联

MySQL数据库基础_第33张图片

4. 外键约束(foreign key)、级联操作(ON UPDATE CASCADE、ON DELETE CASCADE)

i)外键约束

MySQL数据库基础_第34张图片

FK_STUDENTS_CLASSES是外键逻辑名称,可随意起,不用关键字就行。

用insert添加学生时,设置给cid外键列的值必须在其关联的主表classes中class_id列存在。

ii)级联操作

当学生表中存在学生信息关联班级表的某条记录时(被引用),就不能对班级表的这条记录修改ID、删除操作。

MySQL数据库基础_第35张图片

如果硬要改,请update表中的相应的内容。

或者使用级联修改ON UPDATE CASCADE 级联删除ON DELETE CASCADE(有点像添加一个特性?)

MySQL数据库基础_第36张图片

此后在update时会同步修改,在delete一个时,和它关联的另一个也会被删除。

八. 连接查询

在MySQL中可以使用join实现多表的联合查询——连接查询,join按其功能不同分为三个操作。

CREATE TABLE if not EXISTS classes(
	class_id INT PRIMARY KEY auto_increment,
	class_name VARCHAR(40) not null UNIQUE,
	class_remark varchar(200)
);
CREATE TABLE if not EXISTS students(
	stu_num CHAR(8) PRIMARY KEY,
	stu_name VARCHAR(20) not null,
	stu_gender char(2) not null,
	stu_age int not null,
	cid int,
	CONSTRAINT FK_STUDENTS_CLASSES FOREIGN KEY(cid) 
	REFERENCES classes(class_id) ON UPDATE CASCADE ON DELETE CASCADE
);

insert into classes(class_name,class_remark)VALUES('Java2104','...');
insert into classes(class_name,class_remark)VALUES('Java2105','...');
insert into classes(class_name,class_remark)VALUES('Java2106','...');
insert into classes(class_name,class_remark)VALUES('Python2104','...');

insert into students(stu_num,stu_name,stu_gender,stu_age,cid)VALUES('20210101','张三','男',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid)VALUES('20210102','李四','女',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid)VALUES('20210103','王五','男',20,1);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid)VALUES('20210104','赵六','女',20,2);
insert into students(stu_num,stu_name,stu_gender,stu_age,cid)VALUES('20210105','孙七','男',20,2);
insert into students(stu_num,stu_name,stu_gender,stu_age)VALUES('20210106','小红','女',20);
insert into students(stu_num,stu_name,stu_gender,stu_age)VALUES('20210107','小明','男',20);

SELECT * FROM classes;
SELECT * FROM students;
1. 内连接inner join

i)笛卡尔积

ii)内连接条件(一般用on设置两张表连接查询的匹配条件)

2. 左连接left join

显示左表中的所有数据,如果在右表中存在与坐标记录满足匹配条件的数据,则进行匹配;如果右表中不存在匹配数据,则显示为null

MySQL数据库基础_第37张图片

3. 右连接right join

与左连接类似,显示右表中所有记录

MySQL数据库基础_第38张图片

4. 数据表别名

MySQL数据库基础_第39张图片

5. 子查询/嵌套查询

案例1:单行单列,用关系运算符(类似与作为return的值只有一个?)

MySQL数据库基础_第40张图片

案例2:单行多列,用IN或NOT IN关键字

MySQL数据库基础_第41张图片

案例3:虚拟表(记得起别名)

MySQL数据库基础_第42张图片

九. 存储过程

1. 存储过程介绍

MySQL数据库基础_第43张图片

SQL指令运行过程:

①在navicat中,编写并运行SQL语句②通过数据库连接将SQL指令发送到数据库③接受SQL指令④SQL引擎,编译并执行SQL指令⑤执行的结果通过数据库连接发送到navicat⑥

可能存在的问题:

①如果需要多次重复执行相同的SQL,需要重复执行上述过程,时间开销大。

②如果要连续执行多个SQL指令,且第二个指令需要第一个指令的执行结果作为参数。

存储过程:将能够完成特定功能的SQL指令进行封装(SQL指令集),编译之后存储在数据库端,并为它起一个名字,客户端可以直接通过名字调用这个SQL指令集,获取执行结果。

2. 存储过程优缺点

存储过程优点:
1. SQL指令无需客户端编写,通过网络传送,可以节省网络开销,同时避免SQL指令在网络传输过程中被恶意修改,保证安全性;
2. 存储过程经过编译创建并保存在数据库中的,执行时无需重复的进行编译操作,对SQL指令的执行过程进行了性能提升;
3.存储过程中多个SQL指令之间存在逻辑关系,支持流程控制语句(分支,循环),可以实现更为复杂的业务;
 

存储过程的缺点:
1.存储过程是根据不同的数据库进行编译,当需要切换到其他的数据库产品时,要重新编写针对于新数据库的存储过程;
2.存储过程受限于数据库产品,如果需要高性能的优化会成为一个问题;
3在互联网项目中,如果带要数据军的高(连接)并发访问,用存储过程会加大数据库的连接执行时间(因为我们将复杂的业务交给了数据库进行处理)

3. 创建creat procedure、调用call存储过程

创建:

MySQL数据库基础_第44张图片

调用:

MySQL数据库基础_第45张图片

4. 变量的使用(declare、select...into...)

局部变量:定义在存储过程中开始的位置,只能在存储过程内部使用

MySQL数据库基础_第46张图片

用户变量:相当于全局变量,变量名要以@开始

MySQL数据库基础_第47张图片

MySQL数据库基础_第48张图片

将查询结果赋值给变量:select...into...

MySQL数据库基础_第49张图片

尽量少用用户变量,太多用户变量可能会让代码难以理解。

存储过程参数:MySQL存储过程的参数有三种:IN \ OUT \ INOUT

IN是输入参数,OUT是输出参数,INOUT是同时作为输入和输出参数,但建议少用INOUT,这样会降低代码可读性。

5. 流程控制(分支语句、循环语句)

i)分支语句if-then-else

MySQL数据库基础_第50张图片

ii)分支语句case

MySQL数据库基础_第51张图片

(这里的else有点像C++switch中default?)

iii)循环语句while

MySQL数据库基础_第52张图片

iiii)循环语句repeat

MySQL数据库基础_第53张图片

iiiii)循环语句loop

MySQL数据库基础_第54张图片

6. 存储过程的管理

i)查询

MySQL数据库基础_第55张图片

ii)修改

MySQL数据库基础_第56张图片

iii)删除

7. 运用存储过程的案列练习
-- 创建书籍信息表
CREATE table books(
	book_id int primary KEY auto_increment,
	book_name VARCHAR(50) not null,
	book_author VARCHAR(20) not null,
	book_price DECIMAL(10,2) not null,
	book_stock int not null,
	book_desc varchar(200)
);

-- 添加书籍信息
insert into books(book_name,book_author,book_price,book_stock,book_desc)
VALUES('C语言程序设计','Lee',48.80,100,'C语言');
insert into books(book_name,book_author,book_price,book_stock,book_desc)
VALUES('C++快速入门','Zhang',58.80,100,'C++');

-- 创建学生表
CREATE TABLE students(
	stu_num char(4) PRIMARY KEY,
	stu_name VARCHAR(20) NOT NULL,
	stu_gender char(2) NOT NULL,
	stu_age int NOT NULL
);

-- 添加学生信息
insert into students(stu_num,stu_name,stu_gender,stu_age)
VALUES('1001','张三','女',20);
INSERT INTO students(stu_num,stu_name,stu_gender,stu_age)
VALUES('1002','李四','男',21);
INSERT INTO students(stu_num,stu_name,stu_gender,stu_age)
VALUES('1003','王五','女',20);

-- 创建借书记录表
CREATE TABLE records(
	rid int PRIMARY KEY auto_increment,
	snum char(4) not null,
	bid int not null,
	borrow_num int not null,
	is_return int not null, -- 0未归还,1已归还
	borrow_date date not null,
	
	CONSTRAINT FK_RECORDS_STUDENTS FOREIGN KEY(snum)REFERENCES students(stu_num),
	CONSTRAINT FK_RECORDS_BOOKS FOREIGN KEY(bid)REFERENCES books(book_id)
);


-- 创建存储过程实现借书业务
-- a:学号 b:图书id m:借书数量 state: 1借书成功,2学号不存在,3图书不存在,4库存不足
CREATE PROCEDURE proc_borrow_book(IN a char(4),IN b int,IN m int,OUT state int)
BEGIN
-- 判断学号是否存在
	DECLARE stu_count int DEFAULT 0;
	DECLARE book_count int DEFAULT 0;
	DECLARE stock int DEFAULT 0;
	SELECT COUNT(stu_num) INTO stu_count from students WHERE stu_num=a;
	IF stu_count>0 THEN
		-- 学号存在,判断图书是否存在
		SELECT COUNT(book_id)INTO book_count FROM books WHERE book_id=b;
		IF book_count>0 THEN
			-- 图书存在,判断库存
			SELECT book_stock INTO stock FROM books WHERE book_id=b;
			IF stock>=m THEN
				-- 执行借书,生成记录
				insert into records(snum,bid,borrow_num,is_return,borrow_date) 
				VALUES(a,b,m,0,SYSDATE());
				-- 修改库存
				UPDATE books SET book_stock=stock-m WHERE book_id=b;
				-- 借书成功
				SET state=1;
			ELSE
				SET state=4;
			END IF;	
		ELSE
			SET state=3;
		END IF;
	ELSE
		SET state=2;
	END IF;	
END;

-- 调用存储过程借书
SET @state_borrow=-1;
call proc_borrow_book('1001',1,2,@state_borrow);
SELECT @state_borrow FROM DUAL;

-- 还书(健壮性很差,有待完善)
-- 还需要考虑的问题:1.还书数量大于借书数量 2.学号书号不存在 3.等等
CREATE PROCEDURE proc_return_book(IN a char(4),IN b int,IN m int,OUT state int)
-- a:学号 b:图书id m:还书数量 state: 1全还完了,2没还完
BEGIN
	DECLARE need_return int DEFAULT 0;
	SELECT borrow_num FROM records INTO need_return;
	IF m = need_return THEN
		UPDATE records SET is_return=1 WHERE snum=a AND bid=b;
		UPDATE books SET book_stock=book_stock+m WHERE book_id=b;
		SET state=1;
	ELSE
		UPDATE books SET book_stock=book_stock+m WHERE book_id=b;
		SET state=2;
	END IF;
END;

SET @state_return=-1;
call proc_return_book('1001',1,2,@state_return);
SELECT @state_return FROM DUAL;
8. 游标
  1. 问题导入:如果创建一个存储过程,需要返回查询语句查询到的多条数据,如何实现?
  2. 游标的概念

游标可以用来依次取出结果集中的每一条数据——逐条读取查询结果集中的记录(有点像迭代器?)

  1. 游标的使用

声明游标:

MySQL数据库基础_第57张图片

使用完之后记得关闭游标:CLOSE mycursor;

MySQL数据库基础_第58张图片

十. 触发器

1. 触发器的介绍

触发器,是一种特殊的存储过程,但是无需用call来手动调用。当对数据表中的数据执行DML操作时自动会触发。

在MySQL中,只有执行insert\delete\update操作才会触发触发器。

2. 触发器的使用(创建、查看、删除)

i)案列说明

MySQL数据库基础_第59张图片

ii)相关操作

MySQL数据库基础_第60张图片

3. NEW与OLD关键字

触发器用于监听对数据表中数据的insert\delete\update操作,在触发器中通常处理一些DML的关联操作(如添加日志等);我们可以使用NEW和OLD关键字在触发器中获取触发这个触发器的DML所操作的数据。

NEW:用于获取insert添加的数据,update修改后的记录

OLD:用于获取delete删除的数据,update修改前的记录

以下是上一部分的例子:

MySQL数据库基础_第61张图片

十一. 视图

1. 视图的概念

视图,就是由数据库中一张表或多张表根据特定的条件查询出的数据构成的虚拟表。

安全性:只向用户开放视图的访问权限,可以有效保护数据表中的数据。

简单性:用户可查询视图来获取多表数据。

2. 视图的创建和查询

MySQL数据库基础_第62张图片

3. 视图数据的特性

视图是虚拟表,其中的数据是来源于原数据表的,在视图中对数据进行操作(比如向视图中加数据、删除视图中数据)时,会对原表有影响

但是当视图是连接查询的结果的话,是不允许进行删除操作的。

视图的使用建议:对复杂查询进行简化,并且不会对数据进行修改的情况下可以使用视图。

4. 视图的修改和删除

i)修改视图create or replace...

ii)修改视图alter...

iii)删除视图drop(当然不会影响原表中的数据)

MySQL数据库基础_第63张图片

十二. 事务

1. 事务简介

事务是一组操作的集合,它是一个不可分割的工作单位,是一系列流程,事务会把所有的操作作为一个整体向系统提交或撤销操作请求。这些操作要么同时成功,要么同时失败。

2. ACID特性

原子性(Atomicity):多个操作,要么同时成功,要么同时失败。

一致性(Consistency):事务执行前后,数据库中数据是一致的,完整性和一致性不能被破坏。

隔离性(Isolation):数据库允许多个事务同时执行(张三借书时也允许李四借书),多个并行的事务之间不能相互影响。

持久性(Durability):事务完成后,对数据的修改时永久的。

3. MySQL事务管理(start transaction、rollback、commit)

i)自动提交

自动提交:在MySQL中,默认DML指令的执行是自动提交的,当我们执行一个DML指令之后,自动同步到数据库中(先进入连接缓存,然后保存在数据文件)。

ii)事务管理

开启事务start transaction(关闭自动提交),提交事务commit(将连接缓存中的数据存入数据文件),如果在执行的过程中出现异常则回滚rollback,一般会有if..else..判断。

MySQL数据库基础_第64张图片

4. 事务隔离级别

MySQL中,事务隔离级别分为四个:①读未提交②读已提交③可重复读④

i)读未提交(read uncommitted):T2可以读取T1执行但是未提交的数据;可能出现脏读

MySQL数据库基础_第65张图片

ii)读已提交(read committed):T2只能读取T1已经提交的数据;可能虚读(两次读取不一样),也叫不可重复读

MySQL数据库基础_第66张图片

iii)可重复读(repeatable read):T2执行第一次查询之后,在事务结束前其他事务不能修改对应的数据;避免了虚读(不可重复读),但是可能导致幻读(T2对数据表中的数据 进行修改后查询,在查询之前T1向数据表中新增了一条数据,就导致T2以为修改了所有数据,但却查询出了与修改不一致的数据(T1事务新增的数据))

iiii)串行化(serializable):同时只允许一个事务对数据表进行操作;避免了脏读,虚读和幻读。

隔离级别

脏读

虚读

幻读

read uncommitted

read committed

×

repeatable read

×

×

serializable

×

×

×

5. 设置MySQL默认隔离级别

MySQL默认的隔离级别是可重复读,可能幻读。

i)查看MySQL默认隔离级别

ii)设置MySQL默认隔离级别

MySQL数据库基础_第67张图片

十三. 索引(index)

1. 索引概述

索引(index)是帮助MySQL高效获取数据的数据结构(有序),取出数据表中的一列或多列构造成便于查找的结构,生成数据表的目录。

MySQL数据库基础_第68张图片

2. 索引的分类

i)主键索引:在数据表中的主键字段创建索引,这个字段必须被primary key修饰,每张表只能有一个主键。

ii)唯一索引:在数据表中的唯一列创建的索引(unique),此列的所有值只能出现依次,可以为NULL。

iii)普通索引:在普通字段上创建的索引,没有唯一性的限制。

iiii)组合索引:两个及以上字段联合起来创建索引。

说明:建表时,主键和唯一键都会默认生成索引。

3. 创建索引

i)唯一索引

只要这一列的值没有重复,即可以创建唯一索引。

MySQL数据库基础_第69张图片

ii)普通索引和组合索引

MySQL数据库基础_第70张图片

iii)全文索引

MySQL数据库基础_第71张图片

4. 索引的使用

创建过索引之后,无需调用,当根据创建索引的列进行查询时,自动触发。(组合索引需要同时que到其中所有的字段来进行查询才会触发)

i)查询索引的规划(有点查看详情的意味)

MySQL数据库基础_第72张图片

5. 查看索引、删除索引

i)查看

MySQL数据库基础_第73张图片

ii)删除

你可能感兴趣的:(数据库,mysql)