海阔天空

当前时间为:
欢迎大家来到海阔天空https://www.9713job.com,广告合作以及淘宝商家推广请微信联系15357240395

2020Javaweb教程之MySQL约束和多表查询

未分类
2020-10-12 13:50:12
1822677238@qq.com

手机扫码查看

2020Javaweb教程之MySQL约束和多表查询

2020Javaweb教程之MySQL约束和多表查询

第一节 数据完整性

作用:保证用户输入的数据保存到数据库中是正确的。
确保数据的完整性 = 在创建表时给表中添加约束

完整性的分类
实体完整性: 行
域完整性: 列
引用完整性: 学生表(学号 ,姓名) 成绩表( 学号,科目,成绩) 科目表(科目编号,科目名称)

1.1 实体完整性约束

实体:即表中的一行(一条记录)代表一个实体(entity)

实体完整性的作用:标识每一行数据不重复。 实体唯一

约束类型

主键约束(primary key)

唯一约束(unique)

自动增长列(auto_increment)

主键约束(primary key)

​ 注:每个表中要有一个主键。

​ 特点:数据唯一,且不能为null

唯一约束(unique)

特点:数据不能重复。可以为null

自动增长列(auto_increment)

sqlserver数据库 (identity) oracle数据库( sequence)

自动增长不能单独使用,一般需要和主键配合。

给主键添加自动增长的数值,列只能是数值类型

CREATE TABLE users(
id INT AUTO_INCREMENT PRIMARY KEY,#自动增长且主键
username VARCHAR(20) NOT NULL,
identity VARCHAR(18) UNIQUE NOT NULL,#唯一约束不可重复
mobile VARCHAR(11) NOT NULL
)CHARSET=utf8

域完整性约束

域完整性约束的作用:限制此单元格的数据正确,不对其它单元格起作用,域代表当前单元格.
域完整性约束:数据类型、非空约束(not null)、默认值约束(default)
check约束(mysql不支持)check(sex=’男’or sex=’女’)

CREATE TABLE users(
username VARCHAR(20) NOT NULL,#非空约束
sex VARCHAR(2) DEFAULT ‘男’#默认值约束
)CHARSET=utf8

引用完整性约束

外键约束:FOREIGN KEY

外键列的数据类型一定要与主键的类型一致

CREATE TABLE stu(#学生表
sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(5) NOT NULL,
sex VARCHAR(2) DEFAULT ‘男’
)CHARSET=utf8;

CREATE TABLE score(#学生成绩表
id INT PRIMARY KEY AUTO_INCREMENT,
score DOUBLE(5,2) NOT NULL,
CONSTRAINT fk_score_sid FOREIGN KEY(id) REFERENCES stu(sid)
)

INSERT INTO stu(sname,sex)VALUES(‘张三’,’女’)#添加学生
INSERT INTO score(score)VALUES(120.55)#添加成绩

SELECT*FROM stu
SELECT*FROM score


多表查询

多表约束:外键约束。

多表的关系

一对多关系:客户和订单,分类和商品,部门和员工
一对多建表原则:在多的一方创建一个字段,字段作为外键指向一方的主键.

多对多关系

学生和课程:

多对多关系建表原则:需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键.

一对一关系

一个丈夫对应一个妻子

一个员工对应一个简历

在实际的开发中应用不多.因为一对一可以创建成一张表.

两种建表原则

唯一外键对应:在多的一方创建一个外键指向一的一方的主键,将外键设置为unique和非空.

主键对应:让一对一的双方的主键进行建立关系. 唯一 非空

多表查询

多表查询有如下几种:

1 合并结果集;UNION 、 UNION ALL

2 连接查询

内连接 INNER JOIN ON

外连接 OUTER JOIN ON

左外连接 LEFT OUTER JOIN
右外连接 RIGHT OUTER JOIN

子查询

2.2.1 合并结果集

作用:合并结果集就是把两个select语句的查询结果合并到一起!

注意:被合并的两个结果:列数必须相同,列类型可以不同。

合并结果集有两种方式:

UNION:去除重复记录,例如:SELECT*FROM emp UNION SELECT*FROM empno

UNION ALL:不去除重复记录,例如:SELECT*FROM emp UNION ALL SELECT*FROM empno

连接查询

连接查询就是求出多个表的乘积,例如t1连接t2,那么查询出的结果就是t1*t2。

连接查询会产生笛卡尔积,假设集合A={a,b},集合B={0,1,2},则两个集合的笛卡尔积为{(a,0),(a,1),(a,2),(b,0),(b,1),(b,2)}。可以扩展到多个集合的情况。

实例

emp表

CREATE TABLE emp(
id INT AUTO_INCREMENT PRIMARY KEY,
ename VARCHAR(20) NOT NULL,
sex VARCHAR(2) NOT NULL,
identity VARCHAR(18) UNIQUE NOT NULL
)CHARSET=utf8

dept表

CREATE TABLE dept(
deptno INT,
dname VARCHAR(20),
loc VARCHAR(5)
)CHARSET=utf8

执行sql语句:SELECT*FROM emp,dept

使用主外键关系做为条件来去除无用信息
SELECT*FROM emp,dept WHERE emp.`depno`=dept.`deptno`

如果不需要那么多列,可以筛选指定列
SELECT emp.`id`,emp.`ename`,emp.`salary`,dept.`dname` FROM emp,dept WHERE emp.`depno`=dept.`deptno`

内连接

上面连接语句就是内连接,但不是SQL标准中的查询方式,是mysql扩展的功能

SQL标准的内连接为:
SELECT*FROM emp INNER JOIN dept ON emp.`depno`=dept.`deptno`
注意:on后面 主外键关系

外连接

包括左外连接和右外连接,外连接的特点:查询出的结果存在不满足条件的可能。

a.左外连接:以左表为主表,右表是从表

SELECT*FROM emp LEFT JOIN dept ON emp.`depno`=dept.`deptno`

左连接是先查询出左表(即以左表为主),然后查询右表,左表中满足条件和不满足条件都显示出来,右边不满足条件的显示NULL。

外连接

右连接就是先把右表中所有记录都查询出来,然后左表满足条件的显示,不满足显示NULL。例如在dept表中的40部门并不存在员工,但在右连接中,如果dept表为右表,那么还是会查出40部门,但相应的员工信息为NULL。

SELECT*FROM emp RIGHT OUTER JOIN dept ON emp.`depno`=dept.`deptno`

连接查询总结

​ 连接不限于两张表,连接查询也可以是三张、四张,甚至N张表的连接查询。通常连接查询不可能需要整个笛卡尔积,而只是需要其中一部分,那么这时就需要使用条件来去除不需要的记录。这个条件大多数情况下都是使用主外键关系去除。

子查询

一个select语句中包含另一个完整的select语句

子查询就是嵌套查询,即SELECT中包含SELECT,如果一条语句中存在两个,或两个以上SELECT,那么就是子查询语句了。里面的查询叫做子查询,外层的查询叫父查询,一般情况都是先执行子查询,再执行父查询。

子查询出现的位置

​where后,作为被查询的条件的一部分;

from后,作临时表;

当子查询出现在where后作为条件时,还可以使用如下关键字

any 跟结果集里面的多行单列部分进行比较,满足就返回true

all 跟结果里面的多行单列所有进行比较,所有都满足了才返回true

子查询结果集的常见形式

单行单列(用于条件)

多行单列(用于条件)

多行多列(用于表)

 

示例:

1. 工资高于JONES的员工。

分析:

查询条件:工资>JONES工资,其中JONES工资需要一条子查询。

第一步:查询JONES的工资

SELECT sal FROM emp WHERE ename=’JONES’;

第二步:查询高于JONES工资的员工

SELECT * FROM emp WHERE sal > (第一步结果);

结果:

SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE ename=’JONES’);

 

查询与 admin777同一个部门的员工

第一步:查询admin777的部门编号
SELECT depno FROM emp WHERE ename=’admin777′

第二步:查询部门编号等于admin777的部门编号的员工

SELECT * FROM emp WHERE depno=
(SELECT depno FROM emp WHERE ename=’admin777′)

 

工资小于10号部门的所有员工信息

第一步:查询10号部门所有员工工资:
select salary from emp where deptno=10

第二步:查询小于10号部门所有人工资的员工信息
select*from emp where salary <all(第一步)

结果:SELECT * FROM emp WHERE salary<ALL
(SELECT MAX(salary) FROM emp WHERE depno=10)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注