数据库 第一章 MYSQL基础(5)
目录
SQL
多表设计
数据库设计范式(原则)
实例1
实例2
实例3
关联查询
关联条件
内连接(inner join)
左外连接(left join)
右外连接(right join)
基础查询
子查询
含义:
分类:
实例
SQL
多表设计
数据库设计范式(原则)
数据库设计三大范式:
第一范式,确保每列保持原子性(不可再分) 第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就 说明该数据库表满足了第一范式。
第二范式就是要有主键,要求其他字段都依赖于主键。 没有主键就没有唯一性,没有唯一性在数据表中就定位不到这行记录,所以要有主键。 其他字段组成的这行记录和主键表示的是同一行数据,它们只需要依赖于主键,也就成了唯一的。
第三范式,确保每列都和主键列直接相关,要求一个表中不应包含已在其它表中包含的 非主键字段信息.(多表关联时,在一个表中,只关联另一个表的主键即可,不需要关联另个表的非主键)
实例1
学生信息和专业信息关系
● 外键:使用外键引用另外一个数据表的某条记录。
外键列类型与主键列类型保持一致
数据表之间的关联/引用关系是依靠具体的主键(primary key)和外键建立起来的。
create table student(
id int not null auto_increment primary key,
num int,
name varchar(10) majorid int,-- 专业外键
CONSTRAINT 约束名 foreign key(majorid ) references major(id) -- 添加外键约束
);
也可以建好表好后,通过修改表结构添加外键约束
alter table student add CONSTRAINT 约束名 foreign key(majorid ) references major(id)
约束名规则:
FK_ForeignTable_PrimaryTable_On_ForeignColumn
实例2
学生与专业关系 一对多/多对一
-- 设计 专业信息表, 学生与专业信息表有关系
create table major(
id int primary key auto_increment,
name varchar(10),
major_desc varchar(50)
)
-- 修改表 添加列 majorid 称为外键列,外键列只能与另一个表的主键关联
alter table student add column majorid int
-- 修改表 删除列
alter table student drop column majorid
-- 修改表,为外键列添加外键列添加外键约束,保证数据的完整性
-- 添加约束 约束名字 外键列 与哪个表的主键列关联
alter table student add constraint fk_student_on_majorid foreign key(majorid) references major(id)
-- 删除外键约束
alter table student drop constraint fk_student_on_majorid
实例3
学生选课案例 (多对多关系)
-- 创建一个课程表
create table course(
id int primary key auto_increment,
name varchar(20)
)
-- 创建一个学生选课表(学生与课程的关系表)
create table student_course(
studentid int,
courseid int,
constraint fk_student_course_student_on_course foreign key(studentid) references student(id),
constraint fk_student_course_course_on_course foreign key(courseid) references course(id)
)
关联查询
含义:
又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
笛卡尔乘积现象:表1有m行,表2有n行,结果=m*n
-- 查询学生信息 : 学号,姓名,性别,专业名称
select student.num,student.name,student.gender,student.majorid from student,major
select s.num,s.name,s.gender,s.majorid from student as s,major as m
-- 笛卡尔乘积现象,由于两张表关联没有关联条件,用第一张中的每行与关联表中的每一行进行关联
select s.num,s.name,s.gender,s.majorid from student s,major m
发生原因:
没有有效的连接条件
如何避免:
添加有效的连接条件
关联条件
按功能分类:
- 内连接
- 外连接
- 左外连接
- 右外连接
- 自连接
内连接(inner join)
把满足了条件的两张表中的交集数据查询出来
select 结果 from 表1
inner join 表2 on 表1.column1 = 表2.column2
-- 内连接:只把满足条件的列查询出来
-- 写法1(推荐)
select s.num,s.name,s.gender,m.name 学科 from student s inner join major m on s.majorid = m.id
-- 写法2
select s.num,s.name,s.gender,m.name 学科 from student s,major m where s.majorid = m.id
左外连接(left join)
select 结果 from 表1
left join 表2 on 表1.column1 = 表2.column2
-- 外连接 -- 左外连接 不管条件是否成立,都会把左边表中的数据全部査询出来,右边表只会查询出满足条件的数据s
select s.num ,s.name,s.gender,m.name from student s left join major m on s.majorid= m.id
右外连接(right join)
select 结果 from 表1
right join 表2 on 表1.column1 = 表2.column2
-- 外连接 -- 右连接 不管条件是否成立,都会把右边表中的数据全部査询出来,左边表只会查询出满足条件的数据
select s.num ,s.name,s.gender,m.name from student s right join major m on s.majorid= m.id
基础查询
子查询
含义:
出现在其他语句中的select语句,一般子查询多用与查询语句(查询语句中再出现一个查询)
,称为子查询或内查询;
分类:
按子查询出现的位置:
- select后面: 支持标量子查询
- from后面:支持表子查询
- where:支持标量子查询,列子查询
按功能、结果集的行列数不同:
- 标量子查询(结果集只有一行一列)
- 列子查询(结果集只有一列多行)
- 表子查询(结果集一般为多行多列)
实例
-- 标量子查询(查询结果只有一行一列) 适用于select 和 where后面
select s.num,s.name,(select m.name from major m where m.id = s.majorid) from student s
select * from student where height = (select max(height))from student
-- 列子查询(结果集只有一列多行)
select * from student where height in (select height from student where height >1.60 and height<1.99)
-- 表子查询 把一个查询的结果当作一张表,为另一个查询提供数据
-- 一次查询处理不完,写一个查询进行处理
select * from (select name,count(*) c from student group by name) t where t.c>1