MySQL外键约束&SQL查询关键字
1. 外键约束
外键其实就是用来标识表与表之间的数据关系的
简单理解为外键字段是可以让你去到其他表中查找数据
1.1 表与表之间建立关系
表关系总共有四种
一对多
多对多
一对一
没关系
"判断表关系的方式:换位思考"
1. 一对多
以员工和部门为例
先站在员工的基础上
"问"一个员工信息能否对应多个部门信息
"答"不可以
站在部门的基础上
"问"一个部门信息能否对应多个员工信息
"答"可以
此时"结论:"一个可以一个不可以,那么表关系就是"一对多"
员工表是多,部门表是一
"针对一对多的表关系,外键字段建立在多的一方"
# 表关系没有多对一 一说,都是一对多。
"""
使用SQL语句建立真正意义上的表关系,可以先创建不含外键字段的基本表,之后再添加外键字段。
create table emp(
id int primary key auto_increment,
name varchar(32),
age int,
dep_id int,
foreign key(dep_id) references dep(id)
);
create table dep(
id int primary key auto_increment,
dep_name varchar(32),
dep_desc varchar(256)
);
"""
2. 多对多关系
以书籍 与 作者为例
先站在书籍表的基础之上
"问"一本书籍信息能否对应多个作者信息
"答"可以
"问"一个作者信息能否对应多个书籍信息
"结论:"两个都可以,那么表关系就是"多对多"。
# 多对多的表关系,需要单独开设第三张表来存储。(并且第三张表可以不绑定关系)
"""
create table book(
id int primary key auto_increment,
title varchar(32),
price float(6,2)
);
create table author(
id int primary key auto_increment,
name varchar(32),
age int
);
"""
# 关系表
create table book_auth(
in int primary key auto_increment,
book_id int,
auth_id int,
foreign key(book_id) references author(id)
on update cascade
on delete cascade,
foreign key(auth_id) references book(id)
on update cascade
on delete cascade
);
3. 一对一关系
以作者表 与 作者详情表为例
# 外键字段建在任何一方都可以,但是推荐建在查询频率较高的表中。
"""
create table author(
id int primary key auto_increment,
name varchar(32),
age int,
auth_id int unique,
foreign key(auth_id) references author_detail(id)
on update cascade
on delete cascade
);
create table author_detail(
id int primary key auto_increment,
phone varchar(32),
addr varchar(64)
);
"""
1.2 外键约束
1. 在创建表的时候,需要先创建的是被关联表(没有外键字段的表)
2. 在插入数据时,也需要先保证被关联表中有数据。
3. 在插入数据时,外键字段只能填写被关联表中已经存在的数据。
4. 在修改和删除被关联表中的数据的时候,无法直接操作。
如果想要数据之间自动修改和删除,需要添加额外的配置
create table emp1(
id int primary key auto_increment,
name varchar(32),
age int,
dep_id int,
foreign key(dep_id) references dep(id)
on update cascade # 级联更新
on delete cascade
);
create table dep1(
id int primary key auto_increment,
dep_name varchar(32),
dep_desc varchar(256)
);
"""
由于外键有实质性的诸多约束,当表特别多(超过100)的时候,外键的增多反而会增加耦合程度。
所以在实际开发项目中,有时候并不会使用外键创建表关系。
而是通过SQL语句层面,建立逻辑意义上的表关系。
如:操作员工表的sql执行完毕之后,立刻跟着执行部门表的sql。
"""
1.3 操作表的SQL语句补充
# 修改表名
alter table 表名 rename 新表名;
# 增加字段
alter table 表名 add 字段名 数据类型 [完整性约束条件];
alter table 表名 add 字段名 数据类型 first;
alter table 表名 add 字段名 数据类型 after 字段名;
# 删除字段
alter table 表名 drop 字段名;
# 修改字段
alter table 表名 modify
alter table 表名 change
2. SQL查询关键字(重要)
"查询关键字之 select 与 from"
from 控制查询哪张表
select 控制的是查询表里面的哪些字段
2.1 查询关键字之 where 筛选
where 筛选功能
select id from emp where id between 3 and 6;
select id from emp where id>=3 and id<=6;
# 模糊查询关键字:like
%:匹配任意个数的任意字符
_:匹配单个个数的任意字符
"针对NULL 不能用=等于号,只能用is"
1.2 查询关键字之 group by 分组
分组
"""
按照某个指定的条件将单个的个体分成一个个整体
eg:按性别分组,按部门分组,按...分组
"""
# 分组之后默认只能够直接获取到分组的依据,其他数据都不能直接获取
针对5.6需要自己设置sql_mode
set global aql_mode='only_full_group_by';
# 聚合函数
聚合函数主要就是配合分组一起使用的
max min sum count avg
select post,max(salary) from emp group by post;
"group_concat()":分组之后使用
# 可以支持我们获取多个非分组字段,还支持中间拼接符号。
select post,group_concat(name,"|",sex,"|",age) from emp group by post;
select post,group_concat(name) from emp group by post;
"concat":分组之前或不分组使用
select concat(name,sex) from emp;
# 同样也支持拼接
select concat(name,"|",age) from emp;
2.3 查询关键字之 having过滤
"""
where 与 having 都是筛选功能,但是有区别
where在分组之前对数据进行筛选
having在分组之后对数据进行筛选
一定要有一个简单的认识,一条SQL语句的结果可以看成一张全新的表
"""
2.4 查询关键字之 distinct去重
"去重的前提是数据一模一样!!"
select distinct age from emp;
# 原生SQL中用的可能不多,后面django框架中会用的多一些。
2.5 查询关键字之 order by排序
select * from emp order by age;
# 默认升序
select * from emp order by age desc,salary asc;
2.6 查询关键字之 limit 分页
select * from emp limit 3;
select * from emp limit 5,5;
2.7 查询关键字之 regexp正则
select * from emp where name regexp "^j.*(n|y)$";