VueMastery

名称 | 全称 | 简称 |
---|---|---|
数据库 | 存储数据的仓库 ,数据是有组织的进行存储 | DataBase(DB) |
数据库管理系统 | 操纵和管理数据库的大型软件 | DataBase Management System(DBMS) |
SQL | 操作关系型数据库的编程语言 ,定义了一套操作关系型数据库的统一标准 | Structured Query Language(SQL) |
介绍
概念:建立在关系模型基础上,由多张相互连接的二维表组成的数据库。
特点:
- 使用表存储数据,格式统一,便于维护。
- 使用 SQL 语言操作,标准统一,使用方便。
:::
信息拓展:
分类 | 类型 | 大小 | 有符号(SIGNED)范围 | 无符号(UNSIGNED)范围 | 描述 |
---|---|---|---|---|---|
数值类型 | TINYINT | 1 byte | (-128, 127) | (0, 255) | 小整数值 |
SMALLINT | 2 bytes | (-32768, 32767) | (0, 65535) | 大整数值 | |
MEDIUMINT | 3 bytes | (-8388608, 8388607) | (0, 16777215) | 大整数值 | |
INT或INTEGER | 4 bytes | (-2147483648, 2147483647) | (0, 4294967295) | 大整数值 | |
BIGINT | 8 bytes | (-2^63, 2^63 -1) | (0, 2^64 - 1) | 极大整数值 | |
FLOAT | 4 bytes | (-3.402823466 E+38, 3.402823466351 E+38) | 0 和 (1.175494351 E-38, 3.402823466 E+38) | 单精度浮点数值 | |
DOUBLE | 8 bytes | (-1.7976931348623157 E+308, 1.7976931348623157 E+308) | 0 和 (2.2250738585072014 E-308, 1.7976931348623157 E+308) | 双精度浮点数值 | |
DECIMAL | 依赖于M(精度)和D(标度)的值 | 依赖于M(精度)和D(标度)的值 | 小数值(精确定点数) |
分类 | 类型 | 大小 | 描述 |
---|---|---|---|
字符串类型 | CHAR | 0-255 bytes | 定长字符串 |
VARCHAR | 0-65535 bytes | 变长字符串 | |
TINYBLOB | 0-255 bytes | 不超过255个字符的二进制数据 | |
TINYTEXT | 0-255 | 短文本字符串 | |
BLOB | 0-65 535 bytes | 二进制形式的长文本数据 | |
TEXT | 0-65 535 bytes | 长文本数据 | |
MEDIUMBLOB | 0-16 777 215 bytes | 二进制形式的中等长度文本数据 | |
MEDIUMTEXT | 0-16 777 215 bytes | 中等长度文本数据 | |
LONGBLOB | 0-4 294 967 295 bytes | 二进制形式的极大文本数据 | |
LONGTEXT | 0-4 294 967 295 bytes | 极大文本数据 |
分类 | 类型 | 大小 | 范围 | 格式 | 描述 |
---|---|---|---|---|---|
日期类型 | DATE | 3 | 1000-01-01 至 9999-12-31 | YYYY-MM-DD | 日期值 |
TIME | 3 | -838:59:59 至 838:59:59 | HH:MM:SS | 时间值或持续时间 | |
YEAR | 1 | 1901 至 2155 | YYYY | 年份值 | |
DATETIME | 8 | 1000-01-01 00:00:00 至 9999-12-31 23:59:59 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值 | |
TIMESTAMP | 4 | 1970-01-01 00:00:01 至 2038-01-19 03:14:07 | YYYY-MM-DD HH:MM:SS | 混合日期和时间值,时间戳 |
说明:
单行注释:
-- 注释内容
或# 注释内容(MySQL特有)
多行注释:
/* 注释内容 */
分类 | 全称 | 说明 |
---|---|---|
DDL | Data Definition Language | 数据定义语言,用来定义数据库对象(数据库、表、字段) |
DML | Data Manipulation Language | 数据操作语言,用来对数据表中的数据进行增删改查 |
DQL | Dataf Query Language | 数据查询语言,用来查询数据库中表的记录 |
DCL | Data Control Language | 数据控制语言,用来创建数据库用户、控制数据库的访问权限 |
查询所有数据库
show databases;
查询当前使用的数据库
select database();
创建数据库
create database/schema [if not exists] 数据库名 [default charset 字符集] [collate 排序规则];
删除数据库
drop database [if exists] 数据库名;
使用数据库
use 数据库名;
创建数据表
create table 表名(
字段1 字段类型 [comment 字段1注释内容],
字段2 字段类型 [comment 字段2注释内容],
...
)[comment 表注释内容];
示例:
create table user(
id int comment '用户ID',
name varchar(255) comment '姓名',
age int comment '年龄'
) comment '用户表';
查询当前数据库中所有表
show tables;
查询表结构
desc 表名;
查询指定表的建表语句
show create table 表名;
添加字段
alert table 表名 add [column] 字段名 字段类型 [comment 字段注释][约束];
-- 模板: alter table 表名 add 字段信息;
alter table 表名 add 字段1信息,add 字段2信息; -- 一次添加多个字段
示例:
alter table user add column sex varchar(255) comment '性别' check ( sex in ('男','女') );
修改数据类型
alter table 表名 modify 字段名 新数据类型;
示例:
alter table user modify name varchar(50);
修改字段名和字段类型
alter table 表名 change 旧字段名 新字段名 类型 [comment 注释] [约束];
修改表名
alter table 表名 rename to 新表名;
示例:
alter table user rename to admin;
-- 这里我改回为原来的 user 表, 方便演示
alter table admin rename to user;
示例:
alter table user change name username char(50);
删除字段
alter table 表名 drop [column] 字段名;
示例:
alter table user drop username;
删除表
drop table [if exists] 表名;
删除指定表, 并按照之前的表结构重新创建该表
truncate table 表名;
概念
表中的一条数据也称为一条记录。
-- 按照建表字段顺序插入记录: 给表的全部字段添加信息
insert into 表名 values(值1, 值2, ...);
-- 按照指定字段插入记录: 给表的部分字段添加信息
insert into 表名(字段名1, 字段名2, ...) values(值1, 值2, ...);
-- 批量添加数据
insert into 表名 values(值1, 值2, ...),(值1, 值2, ...),...;
insert into 表名(字段名1, 字段名2, ...) values(值1, 值2, ...),(值1, 值2, ...),...;
示例:
insert into user values(1, 18, 'rose', '男');
insert into user values(2, 18, 'jack', '男'), (3, 20, 'john', '男');
-- 不加条件会修改所有记录
update user set 字段名 = 值;
-- 通过条件查询, 修改符合条件的所有记录
update user set 字段名1 = 值1, 字段名2 = 值2, ... [where 条件];
示例:
update user set age = 20;
update user set username = 'jack1', age = 18 where username = 'jack';
-- 不加条件会删除所有记录
delete from 表名 [where 条件];
示例:
-- 删除 id 为 1 的记录
delete from user where id = 1;
select [distinct]
字段列表
from
表名列表
where
条件列表
group by
分组字段列表
having
分组后条件列表
order by
排序字段列表
limit
分页参数
查询多个字段
格式:
select 字段1, 字段2, ... from 表名;
select * from 表名;
设置别名
select 字段1 [as] 别名1, 字段2 [as] 别名2, ... from 表名;
示例
select username 用户名, age as 年龄 from user;
去除重复记录
select distinct 字段列表 from 表名;
格式
select 字段列表 from 表名 where 条件列表;
条件
比较、关系运算符 | 功能 |
---|---|
> | 大于 |
>= | 大于等于 |
< | 小于 |
<= | 小于等于 |
= | 等于 |
<> 或 != | 不等于 |
between...and... | 在某个范围之内(含最小、最大值) |
in(...) | 在 in 之后的列表中的值,多选一 |
like 占位符 | 模糊匹配(_ 匹配单个字符, % 匹配任意个字符) |
is null | 是NULL 的值 |
逻辑运算符 | 功能 |
---|---|
and 或 && | 大于 |
or 或 || | 大于等于 |
not 或 ! | 非, 不是 |
示例 1
select * from user where age >= 18 and age <= 45;
示例 2
select * from user where age between 18 and 45;
示例 3
-- or 的写法可以简化为下面的形式
-- select * from user where age = 18 or age = 45; -- 等价于下面这种
select * from user where age in(18, 45);
示例 4
-- 查询 username 字段中包含 j 字符的记录
select * from user where username like '%j%';
-- 查询 username 字段中是4个字符的记录
select * from user where username like '____';
介绍
聚合函数是将一列数据作为一个整体,进行纵向计算。
常见聚合函数
函数 | 功能 |
---|---|
count | 统计数量 |
max | 最大值 |
min | 最小值 |
avg | 平均值 |
sum | 求和 |
格式
⚠️ 注意:
null
值不参与所有聚合函数运算。
select 聚合函数(字段列表) from 表名;
示例
select sum(age) / count(*) from user;
where
和 having
区别
- 执行时机不同:
where
是分组之前进行过滤,不满足where
条件,不参与分组; 而having
是分组之后对结果进行过滤。- 判断条件不同:
where
不能对聚合函数进行判断,而having
可以。
⚠️ 注意:
执行顺序:
where
>聚合函数
>having
分组之后,查询的字段一般为
分组字段
和聚合函数
,查询其他字段无任何意义。
select 字段列表 from 表名 [where 条件] group by 分组字段名 [having 分组后过滤条件];
示例 1
-- 根据姓名去重并统计性别数量
select sex, count(distinct username) from user group by sex;
示例 2
技巧
先通过where
条件筛选出符合条件的数据,再使用group by
进行分组,最后使用having
对分组进行过滤。
-- 选出所有年龄大于等于18岁的人,根据性别进行分组,统计分组中人数,然后再筛选出人数大于等于2的性别
select sex, count(distinct username) sex_count
from user
where age >= 18
group by sex
having sex_count >= 1;
select 字段列表 from 表名 order by 字段1 排序方式1, 字段2 排序方式2;
- ASC:升序(默认值)
- DESC:降序
示例
select * from user order by age desc;
select 字段列表 from 表名 limit 偏移量, 查询记录数;
偏移量
也称为起始索引
,起始索引从 0 开始,起始索引 = (查询页码 - 1) * 每页显示记录数
- 分页查询是数据库的方言,不同的数据库有不同的实现,MySQL 中是 LIMIT。
- 如果查询的是第一页数据,起始索引可以省略,直接简写为
limit 10
。
use mysql;
select * from user;
create user `用户名`@`主机名` identified by `密码`;
alter user `用户名`@`主机名` identified with `mysql_native_password` by `新密码`;
drop user `用户名`@`主机名`;
示例 1
-- 创建用户 demo,可以任意主机访问该数据库,密码为123456
create user `demo`@`%` identified by '123456';
-- 只能在当前主机登录、访问的话,要将 @ 符号后面的 % 改为 localhost 即可
示例 2
-- 更改用户密码
alter user root@localhost identified with mysql_native_password by '123';
权限 | 说明 |
---|---|
all, all privileges | 所有权限 |
select | 查询数据 |
insert | 插入数据 |
update | 修改数据 |
delete | 删除数据 |
alter | 修改表 |
drop | 删除数据库/表/视图 |
create | 创建数据库/表 |
show grants for `用户名`@`主机名`;
grant 权限列表 on `数据库名`.`表名` to `用户名`@`主机名`;
revoke 权限列表 on 数据库名.表名 from 用户名@主机名;
示例
-- 创建所有计算机均可访问的用户
create user demo@% identified by '密码';
-- 给新创建的用户授予权限
grant all on demo.* to demo@%;
-- 撤销权限
revoke all on demo.user from demo@%;
函数 | 功能 |
---|---|
concat(s1, s2, s3, ...) | 字符串拼接 |
lower(str) | 将字符串 str 全部转为小写 |
upper(str) | 将字符串 str 全部转为大写 |
lpad(str, n, pad) | 左填充,用字符串 pad 对 str 的左边进行填充,达到 n 个字符串长度 |
rpad(str, n, pad) | 右填充,用字符串 pad 对 str 的右边进行填充,达到 n 个字符串长度 |
trim(str) | 去掉字符串头部和尾部的空格 |
substr(str, start, len) | 返回字符串 str 从 start 位置起的 len 个长度的字符串 |
示例
update user set id = lpad(id, 5, '0');
select substr('hello world!', 1, 5);
函数 | 功能 |
---|---|
ceil(x) | 向上取整 |
floor(x) | 向下取整 |
mod(x, y) | 返回 x /y 的模 |
rand() | 返回 0 ~ 1 内的随机数 |
round(x, y) | 求参数x 的四舍五入的值,保留y 位小数 |
示例
-- 随机生成 6 位数验证码
select rpad(round(rand() * 1000000, 0), 6, '0') 六位数随机验证码;
函数 | 功能 |
---|---|
curdate() | 返回当前日期 |
curtime() | 返回当前时间 |
now() | 返回当前日期和时间 |
year(date) | 获取指定 date 的年份 |
month(date) | 获取指定 date 的月份 |
day(date) | 获取指定 date 的日期 |
date_add(date, interval expr type) | 返回一个日期/时间值加上一个时间间隔 expr 后的时间值 |
datediff(date1, date2) | 返回起始时间 date1 和结束时间 date2 之间的天数 |
示例 1
-- 时间增加的函数
select date_add(now(), interval 60 day);
select date_add(now(), interval 24 month);
select date_add(now(), interval 60 year);
示例 2
-- 计算时间差
select datediff('2024-7-7', '2024-7-1') + 1 日期差;
说明
函数 | 功能 |
---|---|
if(value, t, f) | 如果 value 为真,则返回 t,否则返回 f |
ifnull(value1, value2) | 如果 value1 不为空,返回 value1,否则返回 value2 |
case when [val1] then [res1] ... else [default] end | 如果 val1 为真,返回 res1,...否则返回 default 默认值 |
case [expr] when [val] then [res] ... else [default] end | 如果 expr 的值等于 val1,返回 res1,...否则返回 default 默认值 |
示例 1
select if(true, 'success', 'failure') if控制语句;
select ifnull(null, 'Hello world!') ifnull控制语句;
- 概念:约束是作用于表中字段上的规则,用于限制存储在表中的数据。
- 目的:保证数据库中数据的正确、有效性和完整性。、
- 分类如下:
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制该字段的数据不能为 null | not null |
唯一约束 | 保证该字段的所有数据都是唯一、不重复的 | unique |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | primary key |
默认约束 | 保存数据时,如果未指定该字段的值,则采用默认值 | default |
检查约束(8.0.16 版本之后) | 保证字段值满足某一条件 | check |
外键约束 | 用来让两张表的数据之间建立连接,保证数据的一致性和完整性 | foreign key |
⚠️ 注意:约束是作用于表中字段上的,可以在创建表/修改表的时候添加约束。
create table user(
字段名 数据类型,
...
[constraint] [外键名称] foreign key (外键字段名) references 主表(主表列名)
);
alter table 表名 add constraint 外键名称
foreign key(外键字段名) references 主表(主表列名);
alter table 表名 drop foreign key 外键名称;
示例
/* 创建主表 */
create table dept(
id int primary key auto_increment comment '部门ID',
name varchar(15) unique comment '部门名称'
);
insert into dept(name) values('技术部'), ('研发部'), ('物流部');
/* 创建从表 */
create table emp(
id int primary key auto_increment comment '员工ID',
name varchar(15) unique comment '员工姓名',
dept_id int comment '部门ID',
constraint fk_dept_id foreign key(dept_id) references dept(id)
);
/* 删除约束 */
alter table emp drop constraint fk_dept_id;
/* 修改约束 */
alter table emp add constraint fk_dept_id
foreign key emp(dept_id) references dept(id);
/* 展示建表结构 */
show create table emp;
cascade
具有级联操作,当主表中的记录被删除时,主表关联着的从表中对应的外键记录也会跟着被删除。
语法
alter table 表名 add constraint 外键名称
foreign key(外键字段) references 主表名(主表字段名)
on update cascade on delete cascade;
行为 | 说明 |
---|---|
no action | 当主表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 restrict 一致) |
restrict | 当主表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新。(与 no action 一致) |
cascade | 当主表中删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新外键在从表中的记录。 |
set null | 当在主表中删除对应记录时,首先检查该记录是否有对应外键,如果有则设置从表中该外键值为null (这就要求该外键允许取null )。 |
set default | 主表有变更时,从表将外键列设置成一个默认的值(Innodb 不支持) |
表结构之间存在的三种关系基本上分为以下三类:
- 一对一
- 一对多(多对一)
- 多对多
在任意一方加入外键,关联另外一方的主键,并且设置外键为唯一的(unique)
在多的一方建立外键,指向一的一方的主键
建立第三张中间表,中间表至少包含两个外键,分别关联两方主键
多表查询分类:
连接查询
内连接:相当于查询 A、B 交集部分数据
外连接:查询某一张表的所有数据,以及两张表交集部分数据
自连接:当前表与自身的连接查询,自连接必须使用表别名
内连接:相当于查询 A、B 交集部分数据
select 字段列表 from 表1, 表2 where 条件...;
select 字段列表 from 表 [inner] join 表2 on 连接条件...;
示例
create table student(
id int primary key auto_increment,
name varchar(15) unique
);
insert into student(name) values('jack'), ('rose'), ('john'), ('jimmy'), ('blus');
create table score(
id int primary key auto_increment,
sid int unique,
math int unsigned,
english int unsigned,
chinese int unsigned,
constraint fk_sid foreign key (sid) references student(id)
);
insert into score(sid, math, english, chinese) values(1, 71, 88, 64),
(2, 94, 64, 82),
(3, 78, 72, 79),
(4, 94, 92, 97);
-- (1)隐式内连接
select st.name,sc.math, sc.english, sc.chinese
from student st, score sc
where st.id = sc.sid;
-- (2)显式内连接
select st.name, sc.math, sc.english, sc.chinese
from student st
join score sc
on st.id = sc.sid;
外连接:
左表
所有数据,以及两张表交集部分数据select 字段列表 from 表1 left [outer] join 表2 on 条件...;
右表
所有数据,以及两张表交集部分数据select 字段列表 from 表1 right [outer] join 表2 on 条件...;
-- (3)左外连接: 包含左表所有记录,右表没有则显示null
select st.name as '姓名', sc.math as '数学', sc.english as '英语', sc.chinese as '语文'
from student st
left join score sc
on st.id = sc.sid;
-- (4)右外连接: 包含右表所有记录,左表没有则显示null
select st.name as '姓名', sc.math as '数学', sc.english as '英语', sc.chinese as '语文'
from student st
right join score sc
on st.id = sc.sid;
-- (5)使用左连接过滤出没有成绩的学生
select st.name as '姓名', sc.math as '数学', sc.english as '英语', sc.chinese as '语文'
from score sc
left join student st
on st.id = sc.sid
where sc.sid is not null;
select 字段列表 from 表A 别名A join 表A 别名B on 条件...;
自连接查询,可以是内连接查询,也可以是外连接查询。
示例
/**查询员工与所属领导 */
select a.name, b.name from emp a, emp b where a.manager_id = b.id;
对于
union
查询,就是把多次查询的结果合并起来,形成一个新的查询结果集。
select 字段列表 from 表A ...
union [all]
select 字段列表 from 表B ...;
对于联合查询的多张表的列数必须保持一致,字段类型也需要保持一致。
union all
会将全部的数据直接合并在一起,union
会对合并之后的数据去重。
示例: 将薪资低于 5000 的员工,和年龄大于 50 岁的员工全部查询出来
/**同一个人满足多个条件会多条重复的查询记录 */
select * from emp where salary < 5000
union all
select * from emp where age > 50;
/** union 会对查询之后合并的数据去重, 保留满足条件的第一条记录 */
select * from emp where salary < 5000
union
select * from emp where age > 50;
SQL
语句中嵌套select
语句,称为嵌套查询
,又称子查询
。select * from t1 where column1 = (select column1 from t2);
子查询外部的雨具可以是
insert
/update
/delete
/select
的任何一个。
根据子查询结果不同,分为:
根据子查询位置,分为:where
之后、from
之后、select
之后
操作符 | 描述 |
---|---|
in | 在指定的集合范围之内,多选一 |
not in | 不在指定的集合范围之内 |
any | 子查询返回列表中,有任意一个满足即可 |
some | 与 any 等同,使用 some 的地方都可以使用 any |
all | 子查询返回列表的所有值都必须满足 |
示例 1
/**查询比财务部所有人工资都高的员工信息 */
-- a. 查询所有 财务部 人员工资
select id from dept where name = '财务部';
select salary from emp where dept_id = (select id from dept where name = '财务部');
-- b. 比财务部所有人工资都高的员工信息
select * from emp where salary > all (select salary from emp where dept_id = (select id from dept where name = '财务部'));
子查询返回的结果是一行(可以是多列), 这种子查询称为行子查询。
常用的操作符:
=
、< >
、in
、not in
示例
/** 查询与"张无忌"的薪资及直属领导相同的员工信息 */
-- a. 查询"张无忌"的薪资及直属领导
select salary, managerid from emp where name = '张无忌';
-- b. 查询与"张无忌"的薪资及直属领导相同的员工信息
-- select * from emp where salary = 12500 and managerid = 1; -- 下面均等同
-- select * from emp where (salary, managerid) = (12500, 1);
select * from emp where (salary, managerid) = (select salary, managerid from emp where name = '张无忌');
子查询返回的结果是多行多列,这种子查询称为
表子查询
。常用的操作符:
in
示例
/** 查询与"鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息 */
-- a. 查询"鹿杖客" , "宋远桥" 的职位和薪资
select job, salary from emp where name = '鹿杖客' or name = '宋远桥';
-- b. 查询与"鹿杖客" , "宋远桥" 的职位和薪资相同的员工信息
select * from emp where (job, salary) in (select job, salary from emp where name = '鹿杖客' or name = '宋远桥');
解释
-- 查看事务自动提交状态
select @@autocommit;
-- 关闭事务自动提交
set @@autocommit=0;
/**控制事务的两种方式:
(1)关闭事务提交 set @@autocommit=0;
(2)通过 start transaction; 或 begin; 显式开启事务
*/
start transaction;
-- 或者
begin;
commit;
rollback;
介绍
问题 | 描述 |
---|---|
脏读 | 一个事物读到另外一个事务还没有提交的数据 |
不可重复读 | 一个事物先后读取同一条记录,但两次读取的数据不同,称之为不可重复读 |
幻读 | 一个事物按照条件查询数据时,没有对应的数据行,但是在插入数据时,又发现这行数据已经存在,好像出现了"幻影" |
隔离级别 | 脏读 | 不可重复读 | 幻读 |
---|---|---|---|
Read uncomimmited | √ | √ | √ |
Read commited | × | √ | √ |
Repeatable read (mysql 默认) | × | × | √ |
Serializable | × | × | × |
select @@transaction_isolation;
set [session|global] transaction isolation level { read uncommitted | read committed | repeatable read | serializable}