MySQL
基础指令
登陆MySQL:
1 | mysql -u用户名 -p密码 [-h数据库服务器IP地址 -P端口号] |
DDL
数据库
1 | show databases; |
表结构
创建表:
1 | create table 表名( |
例如:
1 | create table user( |
常见的约束:
约束 | 描述 | 关键字 |
---|---|---|
非空约束 | 限制字段不能为null | not null |
唯一约束 | 数据唯一 | unique |
主键约束 | 主键是一行数据的唯一标识,要求非空且唯一 | primary key |
默认约束 | 未指定时使用默认值 | default |
外键约束 | 让两张表的数据建立连接,保证一致性、完整性 | foreign key |
数据类型:
- 数值类型:
- 整形分为
tinyint
、smallint
、mediumint
、int
、bigint
,分别占用1、2、3、4、8字节。 - 浮点数分为
float
、double
,分别占用4、8字节,小数值decimal
(不会出现精度损失)。float(5,2)
中5
表示整个数字长度,2
表示小数位数。在类型后可以指定unsigned
为无符号数。
- 整形分为
字符串类型:
char
定长字符串:char(10)
无论存储内容,均占用10个字符空间,性能比varchar
略高。varchar
变长字符串:varchar(10)
最多占用10个字符空间,占用空间随存储内容变化。blob
存储二进制数据text
存储文本数据
日期类型:
date
:YYYY-MM-DD
time
:HH:MM:SS
year
:YYYY
datetime
:YYYY-MM-DD HH:MM:SS
timestamp
:YYYY-MM-DD HH:MM:SS
,存储时间戳
表的查改删:
1 | show tables; -- 查询当前数据库所有表 |
DML
数据的增删改:
添加数据:
insert
1
2
3
4
5-- 指定字段添加数据
insert into 表名(字段1, 字段2) values (值1, 值2), (值1, 值2);
-- 全部字段添加数据
insert into 表名 values (值1, 值2, ...), (值1, 值2, ...);修改数据:
update
1
2-- 修改数据(注意where, 否则会对所有数据更新)
update 表名 set 字段名1 = 值1, 字段名2 = 值2, ... [where 条件];删除数据:
delete
1
2-- 删除数据(注意where, 否则会删除所有相关数据)
delete from 表名 [where 条件];
注意将值设为null
使用update
。
DQL
数据的查询:select
。
1 | select |
基本查询与条件查询
1 | select 字段列表 from 表名; |
运算符 | 功能 |
---|---|
is null |
判断为null |
between min_val and max_val |
在指定范围内(包含边界) |
in (...) |
在多个值中匹配 |
= |
等于 |
!= 或<> |
不等于 |
like |
模糊匹配,_ 匹配单个字符,% 匹配多个字符 |
分组查询
聚合函数:对列进行纵向计算,所有聚合函数不会统计null
函数 | |
---|---|
count |
统计数量 |
min |
求最小值 |
max |
求最大值 |
sum |
求和 |
avg |
求均值 |
例如:
1 | select count(id) from table1; |
分组查询:
1 | select 分组字段/聚合函数(不能为*) from 表名 [where 条件列表] group by 分组字段名 [having 分组后过滤条件]; |
where
对比having
:
where
在分组前执行,having
在分组后对结果过滤where
不能对聚合函数判断
排序查询
1 | select 字段名 from 表名 order by 排序字段 排序方式; |
排序方式
- 升序(
asc
),默认 - 降序(
desc
)
分页查询
1 | select 字段名 from 表名 limit 起始索引, 查询记录数; |
limit
为mysql
专用的,起始索引从0开始,如果起始索引为0则可省略。前端一般传入页码,需要(页码-1)*每页展示数计算起始索引。
多表关系
一对多:在数据库表中多的一方,添加字段,来关联一的一方的主键。
建立数据库关联:在多的一方添加外键约束关联一的一方。
1 | -- 创建表时添加约束 |
例如:
1 | alter table emp add constraint fk_emp_dept_id foreign key (dept_id) references dept(id); |
删除外键约束:
1 | alter table emp drop foreign key fk_emp_dept_id; |
上述物理外键容易引发死锁问题,同时不适用于分布式数据库,因此目前更常用的方案是在业务层逻辑中解决外键关联问题,即使用逻辑外键,而数据库层面无关联。
一对一:多用于单表拆分,将一张表的基础字段放在一张表中,其他字段放在另一张表中,以提升操作效率。
在任意一方加入外键关联另外一方的主键,并且设置外键为unique
。
多对多:建立第三张中间表,中间表至少包含两个外键,分别关联两方主键。
多表查询
1 | select * from 表名1, 表名2; |
此时会组合表1、表2的所有信息。
通过多表之间的关联过滤:
1 | select emp.id, emp.name from emp, dept where emp.dept_id = dept.id; |
连接查询
内连接:查询A、B交集部分数据
1
2
3
4
5-- 隐式内连接(常用)
select 字段列表 from 表1 [as] 别名1, 表2 [as] 别名2 where 连接条件 ...;
-- 显示内连接
select 字段列表 from 表1 [inner] join 表2 on 连接条件 ...;外连接:
左外连接:查询左表所有数据(常用)
1
2
3
4select 字段列表 from 表1 left [outer] join 表2 on 连接条件;
-- 输出所有员工姓名以及对应的部门名称
select e.name, d.name from emp e left outer join dept on e.dept_id = d.id;右外连接:查询右表所有数据
1
select 字段列表 from 表1 right [outer] join 表2 on 连接条件;
子查询:SQL语句嵌套select语句,称为嵌套查询。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21select * from tl where column1 = (select column1 from t2 ...);
-- 标量子查询
-- 查询最早入职的员工信息
select * from emp where entry_date = (select min(entry_date) from emp);
-- 查询在员工xxx之后入职的员工信息
select * from emp where entry_date > (select entry_date from emp where name = 'xxx');
-- 列子查询
-- 查询"教研部"和"咨询部"下所有的员工信息
select * from emp where dept_id = (select id from dept where name = '教研部' or name = '咨询部');
-- 行子查询
-- 查询与员工xxx的薪资与职位相同的员工信息
select * from emp where salary = (select salary from emp where name = 'xxx') and job = (select job from where name = 'xxx');
-- **简化写法**(推荐)
select * from emp where (salary, job) = (select salary, job from emp where name = 'xxx');
-- 表子查询
-- 获取每个部门中薪资最高的员工信息(将查询项也视为一个表)
select * from emp e, (select dept_id, max(salary) from emp group by dept_id) a where e.dept_id = a.dept_id and e.salary = a.salary;
案例
1 | -- 查询"教研部"的男性员工, 且在"2011-05-01"之后入职的员工信息 |
事务管理
事务是一组操作的集合,事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求,只会同时成功或同时失败。
三步操作:开启事务、提交事务/回滚事务。
1 | start transaction; |
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Eternity's Blog!