MySQL:属于c/s架构的软件
数据库的好处——1.持久化数据到本地2.可以实现结构化查询,方便管理
数据库相关概念
- DB:数据库,保存一组有组织的数据的容器
- DBMS:数据库管理系统,又称为数据库软件(产品),用于管理DB中的数据
- SQL: 结构化查询语言,用于和DBMS通信的语言
数据库存储数据的特点
- 将数据放到表中,表再放到库中
- 一个数据库中可以有多个表,每个表都有一个的名字,用来标识自己。表名具有唯一性。
- 表具有一些特性,这些特性定义了数据在表中如何存储,类似c++中 “类”的设计。
- 表由列组成,我们也称为字段。所有表都是由一个或多个列组成的,每一列类似c++中的”属性”
- 表中的数据是按行存储的,每一行类似于c++中的“对象”。
cmd登陆:mysql -h localhost -P 3306 -u root -p mysql
MySQL的常见命令
# 1.查看当前所有的数据库
show databases;
# 2.打开指定的库
use 库名
# 3.查看当前库的所有表
show tables;
# 4.查看其它库的所有表
show tables from 库名;
# 5.创建表
create table 表名(
列名 列类型,
列名 列类型,
。。。
);
# 6.查看表结构
desc 表名;
# 7.查看服务器的版本
# 方式一:登录到mysql服务端
select version();
# 方式二:没有登录到mysql服务端
mysql --version
mysql --V
SQL的语言分类
DQL(Data Query Language)
:数据查询语言——selectDML(Data Manipulate Language)
:数据操作语言——insert 、update、delete 增删改DDL(Data Define Languge)
:数据定义语言——create、drop、alterTCL(Transaction Control Language)
:事务控制语言——commit、rollback
DQL语言
1:基础查询
- 通过select查询完的结果 ,是一个虚拟的表
- 要查询的东西 可以是常量值、表达式、字段、函数
常用:
distinct
——去重as
——起别名ifnull()
——判断某字段或表达式是否为null,如果为null 返回指定的值,否则返回原本的值isnull()
——判断某字段或表达式是否为null,如果是,则返回1,否则返回0- 加法操作
- select 数值+数值:直接运算
- select 字符+数值:先试图将字符转换成数值,如果转换成功,则继续运算;否则转换成0,再做运算
- select null+值:结果都为null
2:条件查询
条件查询:根据条件过滤原始表的数据,查询到想要的数据
select 要查询的字段|表达式|常量值|函数 from 表 where 条件 ;
分类:
- 条件表达式
> < >= <= = != <>
- 逻辑表达式:
and(&&)
or(||)
not(!)
- 模糊查询
- like:一般搭配通配符使用,可以判断字符型或数值型
- 通配符:%任意多个字符,_任意单个字符,例如:
last_name like 'a%'
between
、and
、in
、is null
、is not null
3:排序查询:order by的位置一般放在查询语句的最后(除limit语句之外)
语法:
select 要查询的东西 from 表 where 条件 order by 排序的字段|表达式|函数|别名 【asc|desc】
4:常见函数
(1)单行函数
- 字符函数
- concat——拼接
- substr——截取子串
- upper——转换成大写————lower——转换成小写
- trim——去前后指定的空格和字符
- ltrim——去左边空格————rtrim——去右边空格
- replace——替换
- lpad——左填充————rpad——右填充
- instr——返回子串第一次出现的索引
- length—— 获取字节个数
- 数学函数
- round ——四舍五入
- rand ——随机数
- floor——向下取整
- ceil——向上取整
- mod——取余
- truncate——截断
- 日期函数
- now——当前系统日期+时间
- curdate——当前系统日期
- curtime——当前系统时间
- str_to_date——将字符转换成日期
- date_format——将日期转换成字符
- 流程控制函数
-
if(条件表达式,表达式1,表达式2):如果条件表达式成立,返回表达式1,否则返回表达式2
-
case语句 处理多分支
# 情况1 case 变量或表达式或字段 when 常量1 then 值1 when 常量2 then 值2 ... else 值n end # 情况2 case when 条件1 then 值1 when 条件2 then 值2 ... else 值n end
(2)分组函数
sum 求和 max 最大值 min 最小值 avg 平均值 count 计数
特点:
1、以上五个分组函数都忽略null值,除了count(*)
2、sum和avg一般用于处理数值型
max、min、count可以处理任何数据类型
3、都可以搭配distinct使用,用于统计去重后的结果
4、count的参数可以支持:字段、*、常量值,一般放1
建议使用 count(*)
5:分组查询
select 查询的字段,分组函数 from 表 group by 分组的字段
特点:
1、可以按单个字段分组
2、和分组函数一同查询的字段最好是分组后的字段
3、分组筛选
针对的表 位置 关键字
分组前筛选: 原始表 group by的前面 where
分组后筛选: 分组后的结果集 group by的后面 having
4、可以按多个字段分组,字段之间用逗号隔开
5、可以支持排序
6、having后可以支持别名
6:多表连接查询
笛卡尔乘积:如果连接条件省略或无效则会出现——解决办法:添加有效的连接条件
sql99语法:通过join
实现连接——1.等值连接、2.非等值连接 (内连接)3.外连接4.交叉连接
select 字段,...
from 表1
【inner|left outer|right outer|cross】join 表2 on 连接条件
【inner|left outer|right outer|cross】join 表3 on 连接条件
【where 筛选条件】
【group by 分组字段】
【having 分组后的筛选条件】
【order by 排序的字段或表达式】
三、自连接——案例:查询员工名和直接上级的名称
SELECT e.last_name,m.last_name
FROM employees e
JOIN employees m
ON e.`manager_id`=m.`employee_id`;
7:子查询
一条查询语句中又嵌套了另一条完整的select语句,其中被嵌套的select语句,称为子查询或内查询
在外面的查询语句,称为主查询或外查询
-
子查询都放在小括号内
-
重点掌握where或having后面:
标量子查询
和列子查询
。 -
子查询优先于主查询执行,主查询使用了子查询的执行结果
-
子查询根据查询结果的行数不同分为以下两类:
-
单行子查询:结果集只有一行,一般搭配单行操作符使用:> < = <> >= <=
-
非法使用子查询:1.子查询的结果为一组值;2.子查询的结果为空
-
多行子查询:结果集有多行,一般搭配多行操作符使用:any、all、in、not in
in: 属于子查询结果中的任意一个就行
any和all往往可以用其他查询代替
-
# 标量子查询
select last_name,salary
from employees
where salary=(
select min(salary) from employees
);
# 列子查询
select last_name
from employees
where employee_id in(
select manager_id
from employees
);
8:分页查询
select 字段|表达式,...
from 表
【where 条件】
【group by 分组字段】
【having 条件】
【order by 排序的字段】
limit 【起始的条目索引,】条目数;
特点:
- 起始条目索引从0开始
- limit子句放在查询语句的最后
- 重要公式:假如每页显示条目数size,要显示的页数 page
select * from 表 limit (page-1)*size,size;
9:联合查询——union:合并、联合,将多次查询结果合并成一个结果
select 字段|常量|表达式|函数 【from 表】 【where 条件】
union 【all】
select 字段|常量|表达式|函数 【from 表】 【where 条件】
union 【all】
select 字段|常量|表达式|函数 【from 表】 【where 条件】
.....
- 多条查询语句的查询的列数必须是一致的
- 多条查询语句的查询的列的类型几乎相同
- union代表去重,union all代表不去重
总结各条查询语句的执行顺序
select 查询列表 # 7
from 表1 别名 # 1
连接类型 join 表2 # 2
on 连接条件 # 3
where 筛选 # 4
group by 分组列表 # 5
having 筛选 # 6
order by排序列表 # 8
limit 起始条目索引,条目数; # 9
DML语言
插入
语法:
insert into 表名(字段名,...)
values(值1,...);
- 字段类型和值类型一致或兼容,而且一一对应
- 可以为空的字段,可以不用插入值,或用null填充
- 不可以为空的字段,必须插入值
- 字段个数和值的个数必须一致
- 字段可以省略,但默认所有字段,并且顺序和表中的存储顺序一致
- 支持查询语句
修改
修改单表语法:★
update 表名 set 字段=新值,字段=新值
【where 条件】
修改多表语法:
update 表1 别名1,表2 别名2
set 字段=新值,字段=新值
where 连接条件
and 筛选条件
删除
方式1:delete语句
单表删除: ★delete from 表名 【where 筛选条件】
方式2:truncate语句
truncate table 表名
两种方式的区别【面试题】
1.truncate不能加where条件,而delete可以加where条件
2.truncate的效率高一丢丢
3.truncate 删除带自增长的列的表后,如果再插入数据,数据从1开始
delete 删除带自增长列的表后,如果再插入数据,数据从上一次的断点处开始
4.truncate删除不能回滚,delete删除可以回滚
DDL语句
库和表的管理
# 一、创建库
create [if not exists] database 库名
# 二、删除库
drop database 库名
# 三、修改库
alter database [if exists] 库名 [character set 字符集名];
表的管理:
# 1.创建表
CREATE TABLE IF NOT EXISTS stuinfo(
stuId INT [约束],
stuName VARCHAR(20) [约束],
gender CHAR [约束],
bornDate DATETIE [约束]
);
DESC studentinfo;
#2.修改表 alter
# 格式
1.添加列
alter table 表名 add column 列名 类型 【first|after 字段名】;
2.修改列的类型或约束
alter table 表名 modify column 列名 新类型 【新约束】;
3.修改列名
alter table 表名 change column 旧列名 新列名 类型;
4 .删除列
alter table 表名 drop column 列名;
5.修改表名
alter table 表名 rename 【to】 新表名;
# 例子:
#①修改字段名
ALTER TABLE studentinfo CHANGE COLUMN sex gender CHAR;
#②修改表名
ALTER TABLE stuinfo RENAME [TO] studentinfo;
#③修改字段类型和列级约束
ALTER TABLE studentinfo MODIFY COLUMN borndate DATE ;
#④添加字段
ALTER TABLE studentinfo ADD COLUMN email VARCHAR(20) first;
#⑤删除字段
ALTER TABLE studentinfo DROP COLUMN email;
# 3.删除表
DROP TABLE [IF EXISTS] studentinfo;
表的复制
INSERT INTO author VALUES
(1,'村上春树','日本'),
(2,'莫言','中国'),
(3,'冯唐','中国'),
(4,'金庸','中国');
#1.仅仅复制表的结构
CREATE TABLE copy LIKE author;
#2.复制表的结构+数据
CREATE TABLE copy2
SELECT * FROM author;
#只复制部分数据
CREATE TABLE copy3
SELECT id,au_name
FROM author
WHERE nation='中国';
#仅仅复制某些字段
CREATE TABLE copy4
SELECT id,au_name
FROM author
WHERE 0;
常见类型
对于一个关系表,除了定义每一列的名称外,还需要定义每一列的数据类型。关系数据库支持的标准数据类型包括数值、字符串、时间等:
名称 | 类型 | 说明 |
---|---|---|
INT | 整型 | 默认是有符号型,无符号添加unsigned关键字或者zerofill |
BIGINT | 长整型 | 8字节整数类型,范围约+/-922亿亿 |
REAL | 浮点型 | 4字节浮点数,范围约+/-1038 |
DOUBLE | 浮点型 | 8字节浮点数,范围约+/-10308 |
DECIMAL(M,N) | 高精度小数 | 由用户指定精度的小数,例如,DECIMAL(20,10)表示一共20位,其中小数10位,通常用于财务计算 |
CHAR(N) | 定长字符串 | 存储指定长度的字符串,例如,CHAR(100)总是存储100个字符的字符串 |
VARCHAR(N) | 变长字符串 | 存储可变长度的字符串,例如,VARCHAR(100)可以存储0~100个字符的字符串 |
BOOLEAN | 布尔类型 | 存储True或者False |
DATE | 日期类型 | 存储日期,例如,2018-06-22 |
TIME | 时间类型 | 存储时间,例如,12:20:59 |
DATETIME | 日期和时间类型 | 存储日期+时间,例如,2018-06-22 12:20:59 |
一、数值型
1、整型
tinyint(1)、smallint(2)、mediumint(3)、int/integer(4)、bigint(5)
特点:
①都可以设置无符号和有符号,默认有符号,通过unsigned设置无符号
②如果超出了范围,会报out or range异常,插入临界值
③长度可以不指定,默认会有一个长度
长度代表显示的最大宽度,如果不够则左边用0填充,但需要搭配zerofill,并且默认变为无符号整型
2、浮点型
定点数:decimal(M,D)
浮点数:
float(M,D) 4
double(M,D) 8
特点:
①M代表整数部位+小数部位的个数,D代表小数部位
②如果超出范围,则报out or range异常,并且插入临界值
③M和D都可以省略,但对于定点数,M默认为10,D默认为0
④如果精度要求较高,则优先考虑使用定点数
二、字符型
char、varchar、binary、varbinary、enum、set、text、blob
char:固定长度的字符,写法为char(M),最大长度不能超过M,其中M可以省略,默认为1
varchar:可变长度的字符,写法为varchar(M),最大长度不能超过M,其中M不可以省略
三、日期型
year年
date日期
time时间
datetime 日期+时间 8
timestamp 日期+时间 4 比较容易受时区、语法模式、版本的影响,更能反映当前时区的真实时间
常见约束
- NOT NULL
- DEFAULT
- UNIQUE
- CHECK(MySQL不支持)
- PRIMARY KEY
- FOREIGN KEY
通用写法:
CREATE TABLE IF NOT EXISTS stuinfo(
id INT PRIMARY KEY, # 列级约束
stuname VARCHAR(20),
sex CHAR(1),
age INT DEFAULT 18,
seat INT UNIQUE,
majorid INT,
CONSTRAINT fk_stuinfo_major FOREIGN KEY(majorid) REFERENCES major(id) # 表级约束
);
主键和唯一的对比:
名称 | 唯一性 | 是否能为空 | table中个数 | 是否允许组合 |
---|---|---|---|---|
primary key | √ | × | 至多1个 | √:不推荐 |
unique | √ | √ | 可以有多个 | √:不推荐 |
外键:
1、要求在从表设置外键关系
2、从表的外键列的类型和主表的关联列的类型要求一致或兼容,名称无要求
3、主表的关联列必须是一个key(一般是主键或唯一)
4、插入数据时,先插入主表,再插入从表
删除数据时,先删除从表,再删除主表
数据库事务TCL
Transaction Control Language 事务控制语言
通过一组逻辑操作单元(一组DML——sql语句),将数据从一种状态切换到另外一种状态
特点:(ACID)[面试重点]
- 原子性:要么都执行,要么都回滚
- 一致性:保证数据的状态操作前和操作后保持一致
- 隔离性:多个事务同时操作相同数据库的同一个数据时,一个事务的执行不受另外一个事务的干扰
- 持久性:一个事务一旦提交,则数据将持久化到本地,除非其他事务对其进行修改
相关步骤:
# 1、开启事务
set autocommit=0;
start transaction;
# 2、编写事务的一组逻辑操作单元(多条sql语句)
select insert update delete
# 3、提交事务或回滚事务
rollback; # 回滚
commit; # 提交
事务的分类
- 隐式事务,没有明显的开启和结束事务的标志
比如insert、update、delete语句本身就是一个事务 - 显式事务,具有明显的开启和结束事务的标志
1、开启事务——取消自动提交事务的功能
2、编写事务的——组逻辑操作单元(多条sql语句)
3、提交事务或回滚事务
事务的隔离级别:
事务并发问题如何发生?
当多个事务同时操作同一个数据库的相同数据时
事务的并发问题有哪些?
- 脏读:一个事务读取到了另外一个事务未提交的数据
- 不可重复读:同一个事务中,多次读取到的数据不一致
- 幻读:一个事务读取数据时,另外一个事务进行更新,导致第一个事务读取到了没有更新的数据
事务的隔离级别
级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
read uncommitted | √ | √ | √ |
read committed | × | √ | √ |
repeatable read | × | × | √ |
serializable | × | × | × |
脏读针对更新,幻读针对插入
设置隔离级别:
set session|global transaction isolation level 隔离级别名;
查看隔离级别:
select @@tx_isolation;
设置保存点 setpoint
SET autocommit=0;
START TRANSACTION;
DELETE FROM account WHERE id=25;
SAVEPOINT a;#设置保存点
DELETE FROM account WHERE id=28;
ROLLBACK TO a;#回滚到保存点
SELECT * FROM account;
视图:一张虚拟的表
视图和表的区别:
名称 | 关键字 | 是否占用物理空间 | 使用 |
---|---|---|---|
视图 | create view | 只是保存了sql逻辑 | 一般是只查看 |
表 | create table | 保存了数据 | 增删改查 |
应用场景:
- 多个地方用到同样的查询结果
- 该查询结果使用的SQL语句较复杂
视图的好处:
- sql语句提高重用性,效率高
- 和表实现了分离,提高了安全性
视图的创建
语法:
CREATE VIEW 视图名
AS
查询语句;
视图的增删改查
增删改影响原始表的结构,所以下面的语句几乎不用!
# 1、查看视图的数据 ★
SELECT * FROM my_v4;
SELECT * FROM my_v1 WHERE last_name='Partners';
2、插入视图的数据
INSERT INTO my_v4(last_name,department_id) VALUES('虚竹',90);
3、修改视图的数据
UPDATE my_v4 SET last_name ='梦姑' WHERE last_name='虚竹';
# 4、删除视图的数据
DELETE FROM my_v4;
某些视图不能更新
- 分组函数、distinct、group by、having、union或者union all
- 常量视图
- Select中包含子查询
- join
- from一个不能更新的视图
- where子句的子查询引用了from子句中的表
视图逻辑的更新
# 方式一:
CREATE OR REPLACE VIEW test_v7
AS
SELECT last_name FROM employees
WHERE employee_id>100;
# 方式二:
ALTER VIEW test_v7
AS
SELECT employee_id FROM employees;
视图的删除
# 可以同时删除多个
DROP VIEW test_v1,test_v2,test_v3;
视图结构的查看
DESC test;
SHOW CREATE VIEW test;
变量
- 系统变量
- 全局变量
- 会话变量
- 自定义变量
- 用户变量
- 局部变量
#1全局变量
/*
作用域:针对于所有会话(连接)有效,但不能跨重启
*/
#①查看所有全局变量
SHOW GLOBAL VARIABLES;
#②查看满足条件的部分系统变量
SHOW GLOBAL VARIABLES LIKE '%char%';
#③查看指定的系统变量的值
SELECT @@global.autocommit;
SELECT @@tx_isolation;
#④为某个系统变量赋值
SET @@global.autocommit=0;
SET GLOBAL autocommit=0;
#2会话变量
/*
作用域:针对于当前会话(连接)有效
*/
#①查看所有会话变量
SHOW SESSION VARIABLES;
#②查看满足条件的部分会话变量
SHOW SESSION VARIABLES LIKE '%char%';
#③查看指定的会话变量的值
SELECT @@autocommit;
SELECT @@session.tx_isolation;
#④为某个会话变量赋值
SET @@session.tx_isolation='read-uncommitted';
SET SESSION tx_isolation='read-committed';
# 用户变量 和 局部变量
#案例:声明两个变量,求和并打印
#用户变量
SET @m=1;
SET @n=1;
SET @sum=@m+@n;
SELECT @sum;
#局部变量
DECLARE m INT DEFAULT 1;
DECLARE n INT DEFAULT 1;
DECLARE SUM INT;
SET SUM=m+n;
SELECT SUM;
用户变量和局部变量的对比
作用域 | 定义位置 | 语法 | |
---|---|---|---|
用户变量 | 当前会话 | 会话的任何地方 | 加@符号,不用指定类型 |
局部变量 | 定义它的BEGIN END中 | BEGIN END的第一句话 | 一般不用加@,需要指定类型 |
存储过程
一组经过预先编译的
sql
语句的集合,理解成批处理语句
好处:
- 提高了sql语句的重用性,减少了开发程序员的压力
- 提高了效率
- 减少了传输次数
分类:
- 无返回无参
- 仅带in类型,无返回有参
- 仅带out类型,有返回无参
- 既带in又带out,有返回有参
- 带inout,有返回有参
注意:in、out、inout都可以在一个存储过程中带多个
参数列表包含三部分:参数模式、参数名、参数类型
,例子——in stuname varchar(20)
创建存储过程
语法:
DELIMITER $
create procedure 存储过程名(in|out|inout 参数名 参数类型,...)
begin
存储过程体
end $
注意
1、需要设置新的结束标记
2、存储过程体中可以有多条sql语句,如果仅仅一条sql语句,则可以省略begin end
3、参数前面的符号的意思
in:该参数只能作为输入 (该参数不能做返回值)
out:该参数只能作为输出(该参数只能做返回值)
inout:既能做输入又能做输出
调用存储过程
call 存储过程名(实参列表)
##函数
###创建函数
学过的函数:LENGTH、SUBSTR、CONCAT等
语法:
CREATE FUNCTION 函数名(参数名 参数类型,...) RETURNS 返回类型
BEGIN
函数体
END
调用函数
SELECT 函数名(实参列表)
函数和存储过程的区别
关键字 调用语法 返回值 应用场景
函数 FUNCTION SELECT 函数() 只能是一个 一般用于查询结果为一个值并返回时,当有返回值而且仅仅一个
存储过程 PROCEDURE CALL 存储过程() 可以有0个或多个 一般用于更新
流程控制结构
分支
一、if函数
语法:if(条件,值1,值2)
特点:可以用在任何位置
二、case语句
语法:
情况一:类似于switch
case 表达式
when 值1 then 结果1或语句1(如果是语句,需要加分号)
when 值2 then 结果2或语句2(如果是语句,需要加分号)
...
else 结果n或语句n(如果是语句,需要加分号)
end 【case】(如果是放在begin end中需要加上case,如果放在select后面不需要)
情况二:类似于多重if
case
when 条件1 then 结果1或语句1(如果是语句,需要加分号)
when 条件2 then 结果2或语句2(如果是语句,需要加分号)
...
else 结果n或语句n(如果是语句,需要加分号)
end 【case】(如果是放在begin end中需要加上case,如果放在select后面不需要)
特点:
可以用在任何位置
三、if elseif语句
语法:
if 情况1 then 语句1;
elseif 情况2 then 语句2;
...
else 语句n;
end if;
特点:
只能用在begin end中!!!!!!!!!!!!!!!
三者比较:
应用场合
if函数 简单双分支
case结构 等值判断 的多分支
if结构 区间判断 的多分支
循环
【标签:】WHILE 循环条件 DO
循环体
END WHILE 【标签】;
特点:
只能放在BEGIN END里面
如果要搭配leave跳转语句,需要使用标签,否则可以不用标签
leave类似于java中的break语句,跳出所在循环!!!