文章目录

  • 五大约束三大范式
  • 主键约束:
  • 非 null约束
  • 唯一约束 :
  • 外键约束:
  • 表与表之间存在的关系
  • 三大范式:
  • 自增长策略
  • delete 与truncate 区别:
  • 多表进行查询:
  • 等值查询
  • 非等值查询
  • 内连接查询
  • 左外连接
  • 右外连接:
  • 子查询
  • 练习:


五大约束三大范式

五大约束: 主键 唯一 非null 外键约束 默认约束

主键约束:

作用:确保数据的唯一性

关键字是: primary key

特点:

  1. 唯一,不能重复
  2. 每一张里只能存在一个主键
  3. 不能为null
  4. 可以设置联合主键(也就是使用两个字段来确定这个主键)

设置主键的三种方法

第一类的第一种 :在创建表的时候,给其设置

CREATE   TABLE  p1(
   pid  INT(4) PRIMARY KEY,
   pname  VARCHAR(20));

第一类的第二种:

CREATE  TABLE  p2(
    pid  INT(4),
    pname VARCHAR(20),
     PRIMARY KEY(pid));

第二类:不在创建表的时候给其设置

CREATE  TABLE  p3(
    pid  INT(4),
    pname VARCHAR(20),
     );
//语法:alter  table  + 表名 add  constraint  主键的别名  + primary key(指定的列(主键一般是id))
ALTER  TABLE  p3 ADD CONSTRAINT   pk_p3    PRIMARY  KEY(pid)

第三类:设置联合主主键既 单独的一列是可以重复的,但联合的内容就不能重复了

CREATE  TABLE p4(
   pid INT(4),
   pname VARCHAR(20),
   PRIMARY KEY(pid,pname)   
   );

删除主键:

//语法    alter  table   表名  drop  primary key ==>因为表里的主键只有一个
ALTER  TABLE   p4 DROP    PRIMARY KEY//删除表p4的主键

非 null约束

作用:给其字段加上非null约束,这个字段是不能为null,

特点:可以重复 ,可以给多个列设置

语法:not null

唯一约束 :

特点:唯一,不能重复

关键字:unique

主键约束的区别:

  1. 主键约束在表里只能有一个,唯一约束是可以有多个
  2. 主键约束不能为null,唯一约束是可以为null

三种创建唯一约束的写法:

  1. 在创建表的时候创建:
create  table   p6(
pid  int(4) primary  key ,
 pname varchar(20) unique );
  1. 第二种写法:
create   table  p8(
 pid  int(4),
pname varchar(20),
 pwd  varchar(20),
unique(pname) );
  1. 第三种写法
create   table  p9(//先创建表
 pid  int(4),
pname varchar(20),
 pwd  varchar(20));
 //语法:alter   table   表名   add constraint  唯一约束的名字(可以省略) unique(列的名字)

alter  table p10 add constraint u_p9  unique(pname)

删除唯一约束:

语法:alter table  + 表名 + drop   index(索引)+(名字)

alter  table p11 drop index  u_p11

外键约束:

原因:就是因为关系型数据库,表与表之间存在的关系
作用:把表与表之间进行关联
关键字: foreign key

设置外键的语法:
alter  table 从表名  add  [constraint fk_stu] 设置外键名称,也就是index名  foreign key(从表外键的列)   references  主表(主键)
例子:
 alter  table  student add  constraint fk_stu  foreign key(tid)  references  teacher(tid);
删除外键的语法:
alter table    表名   drop   foreign key  外键的名称  (只能删除外键,并不能删除外键的索引)
例子:
alter  table  student drop   foreign key fk_stu

注意事项:

  1. 设置到两张表 : 主表(一的一方) teacher 从表(多的)外键是设置在多的一方
  2. 主表的主键对应从表的外键
  3. 主键的大小以及长度必须与外键的相同
  4. 增加数据的时候,必须先增加主表里的数据 ,删除的时候,需要先删除从表,再删除主表的信息(保证数据的完整性)

表与表之间存在的关系

一对多,一对一,多对多

为什么会存在关系?

  1. 需要把电报办公修改成服装 ==> 影响的行数是3 ==》效率低 ==>如图
  2. 修改10000个这个数据 ==> 影响的行数是10000

java通过表名和字段名获取数据_主键


java通过表名和字段名获取数据_主键_02


注意多对多关系表的创建

三大范式:

一:每一个列都是一个原子单位: (不能进行再拆分)

二:每一个表都是描述的一种事务,每一个字段都只能与主键产生依赖关系

三:不能出现传递的依赖(局部依赖) a–>b–>c(错误) 学生编号 <== 学生所有院校 <== 学生所在 院校的名称 局部依赖

注:范式现在最高到六范式了

自增长策略

关键字: auto_increment

注意:

  1. 一般针对于整形
  2. 一般是给主键设置自增长
  3. 在插入的时候自增长不需要进行插入(i++,也就是每次自增长1)

delete 与truncate 区别:

delete: 只删除数据,不影响表的结构

truncate :删除整张表,重现构建一张新表(表结构会发生改变)

多表进行查询:

等值查询

语法: select * from 表名 别名1,表2,别名2 where 关键的id

#等值查询会实现自然连接,自然连接会对重复的相等的列名进行去重并会去除重复无关数据

 select   * from  product as  p ,category as c  where  p.cid = c.cid

非等值查询

语法: select * from 表名 别名1,表2,别名2

select   * from  product  p ,category  c 

注:非等值查询没有意义,会发生笛卡尔积效应,存在大量冗余数据

内连接查询

关键字:inner join(左表与右表可以互换位置) on 匹配的条件
注意:内连接=等值查询,取的值是两个表的交集部分

#查询参加了考试的同学信息(学号、学生姓名(学生表)、科目编号、分数(分数表))  
select s.studentNo,s.studentName, r.subjectNo,r.studentResult   from result as r   
inner  join student as s   on  s.studentNo=r.studentNo

左外连接

以左表为基准,右表一一匹配,能匹配上的,都正常显示,不能匹配,左表数据依然显示, 右表的数设置为null

关键 字:left join on

#查询出了所有同学,不考试的也查出来 ==>不管是否参加考试,都需要查询
 select  s.studentNo,s.studentName,r.subjectNo,r.studentResult from  
student as  s left  join  result as r on s.studentNo = r.studentNo

右外连接:

以右表为基础,左表一一匹配,如果能够匹配上,正常显示,不能匹配,右边数据依然显示, 右表的数据设置为null

关键字 right join on

三种连接方式的取值范围:

java通过表名和字段名获取数据_外键_03

子查询

一个查询语句嵌套另一个完整的查询语句

注意问题:如果是三种表或者是多张表的时候,找到中间表result,通过中间表进行表和表的关联

三张表取值的关系问题:取交集,第一次取的是两个表的交集,第二次是用前两个表的交集 和另外一个表取交集

java通过表名和字段名获取数据_外键_04

有两种子查询:

第一种子查询,把子查询查询的结果,当成条件给另一个查询语句使用

#查询课程为《高等数学-2》且分数不小于80分的学生的学号和姓名
select   s.StudentNo,s.StudentName from student s where s.StudentNo in
(select r.StudentNo from result r
where r.StudentResult>=80 and r.SubjectNo in 
(select sub.SubjectNo from `subject` sub where sub.subjectname='数据库结构-2' ))

第二种子查询:把子查询直接当成是一个结果(也就是查询出来的属性使用)

select s.studentNO ,s.name (select r.studentResult from result as r 
where r.studenNO=s.studentNo) from student as s

练习:

#查询参加了考试的同学信息(学号、学生姓名、科目编号、分数)//两个表等值查询
select  s.StudentNo ,s.StudentName ,r.SubjectNo  as "科目编号",r.StudentResult as "分数"from student as s,result as r  where s.StudentNo=r.StudentNo
#内连接和等值查询查询的都是两个表的交集的数据
#另外一种写法 使用内连接的写法 :select * from 左表 inner join 右表 on 等值的条件 (还可以加where进行筛选)
select  student.StudentNo ,student.StudentName ,result.SubjectNo  as "科目编号",result.StudentResult as "分数"from student inner join result on student.StudentNo=result.StudentNo

#查询出了所有同学,不考试的也查出来 (左外连接)select * from 左表 left join 右表 on 等值的条件(如果有条件还可以加where进行筛选)
select s.StudentNo,s.StudentName,r.SubjectNo,r.StudentResult from student as s left join result r on r.StudentNo=s.StudentNo

#查一下缺考的同学(加where进行筛选)
select s.StudentNo,s.StudentName,r.SubjectNo,r.StudentResult from student as s left join result r on r.StudentNo=s.StudentNo where  r.StudentResult is null
#思考题:查询参加了考试的同学信息(学号、学生姓名、科目名、分数)

select  student.StudentNo,student.StudentName,`subject`.SubjectName,result.StudentResult from student, result,`subject` where student.StudentNo=result.StudentNo and result.SubjectNo=`subject`.SubjectNo

#内连接的写法:
select  student.StudentNo,student.StudentName,`subject`.SubjectName,result.StudentResult from student inner join result on student.StudentNo=result.StudentNo inner join `subject` on result.SubjectNo=`subject`.SubjectNo 

# 查询《数据库结构-1》的所有考试结果,并按成绩由高到低排列
select student.StudentNo,student.StudentName,`subject`.SubjectName,result.StudentResult from student,result,`subject` where student.StudentNo=result.StudentNo  and result.SubjectNo=`subject`.SubjectNo and `subject`.SubjectName="数据库结构-1" order by  result.StudentResult  desc

#内连接的写法:
select s.StudentNo,s.StudentName,su.SubjectName,r.StudentResult from student as s inner join  result as r on s.StudentNo=r.StudentNo inner join `subject` as su  on r.SubjectNo=su.SubjectNo where su.SubjectName="数据库结构-1" order by  r.StudentResult  desc

#查询所有课程《数据库结构-2》的考试成绩,并按照由高到低的显示,同时把该成绩对应的学生的学号、姓名打印出来
select s.StudentNo,s.StudentName,su.SubjectName,r.StudentResult from student as s inner join  result as r on s.StudentNo=r.StudentNo inner join `subject` as su  on r.SubjectNo=su.SubjectNo where su.SubjectName="数据库结构-2" order by  r.StudentResult  desc

#查询课程为《高等数学-2》且分数不小于80分的学生的学号和姓名
select student.StudentNo,student.StudentName from student where student.StudentNo
in(select result.StudentNo from result where result.StudentResult>80 and result.SubjectNo in(select `subject`.SubjectNo from `subject` where `subject`.SubjectName="高等数学-2"))

#案例 :查询《C语言1》的前5名学生成绩信息
select student.StudentNo,student.StudentName,result.StudentResult ,
`subject`.SubjectName from 
student inner join  result on student.StudentNo=result.StudentNo 
inner join `subject` on result.SubjectNo=`subject`.SubjectNo where
`subject`.SubjectName="C语言-1"  order by result.StudentResult  desc limit 0,5

#查询课程为《JAVA第一学年》成绩前10名分数大于80的学生信息(学号,姓名,课程名,分数)使用内连接和子查询写法
select student.StudentNo,student.StudentName from student  inner join result on student.StudentNo=result.StudentNo
where result.StudentResult>80 and result.SubjectNo in
(select `subject`.SubjectNo from `subject` where `subject`.SubjectName="JAVA第一学年")
order by result.StudentResult desc limit 0,10
 
#按照不同的课程,分别算出其平均分、最高分和最低分,对于低于60分平均分的不予显示
select sub.subjectName,avg(r.studentResult),MAX(r.studentResult),MIN(r.studentResult)   from `subject`sub inner join result r on sub.subjectNo=r.subjectNo group by sub.subjectNo having avg(r.studentResult)>60
/*查询密码长度不足6位的学员信息(学员编号、姓名、密码、年级名称)*/
select student.StudentNo,student.StudentName,student.LoginPwd,grade.GradeName
from student inner join grade on student.GradeId=grade.GradeID where length(student.LoginPwd)<6
/*查找李东方所有考试的成绩(科目名称、考试成绩)*/
select student.StudentNo,student.StudentName,`subject`.SubjectName,result.StudentResult
from student inner join result on student.StudentNo =result.StudentNo
 inner join `subject`on `subject`.SubjectNo=result.SubjectNo where student.StudentName="李东方"
/*使用表连接方式查询所有大一年级学员学号、姓名及年级名称*/
select student.StudentNo,student.StudentName,grade.GradeName from student
 inner join grade  on student.GradeId=grade.GradeID where grade.GradeName="大一"
/*使用子查询方式查询所有大一年级学员学号、姓名、年级ID*/
select student.StudentName,student.StudentNo,student.GradeId from student where 
student.GradeId in(select grade.GradeID from grade where grade.GradeName="大一")
#使用子查询此时是无法查询年级姓名的
/*使用表连接方式查询“Java”课程至少一次考试刚好等于60分的学生姓名*/
select student.StudentName,result.StudentResult,`subject`.SubjectName from
student inner join result on student.StudentNo=result.StudentNo inner join
`subject` on result.SubjectNo=`subject`.SubjectNo
where result.StudentResult=60 and `subject`.SubjectName like "java%"
/*使用子查询方式查询“Java”课程至少一次考试刚好等于60分的学生*/

select student.StudentName  from student where student.StudentNo in
(select result.StudentNo from result where result.SubjectNo in(select `subject`.SubjectNo from `subject` where `subject`.SubjectName like "java%")
 and result.StudentResult=60)

/*使用子查询方式+表连接方式混合查询“Java”课程至少一次考试刚好等于60分的学生*/
select student.StudentName from student inner join result on  student.StudentNo= result.StudentNo where result.SubjectNo in (select `subject`.SubjectNo from `subject` where `subject`.SubjectName like "java%" and result.StudentResult=60)
 #用两种方式对数据库进行备份与恢复