定义:结合两个或多个表来执行SQL数据库操作,这通常涉及到一个或多个表的关联,基于某些共享的列(通常是键)之间的关系。
特点:
简化数据;
提高复用性;
方便权限控制;
提高系统的稳定性和负载能力。
二、多表关系一对多:
定义:主表的一条记录可以对应从表的多条记录;
例子:部门表,员工表;
建表原则:在一对多关系中,多的表定位从表,设置外键指向主表。
多对多:
定义:主表的多条记录可以对应从表的多条记录;
例子:商品信息表,客户表,订单表;
建表原则:需要创建第三张表作为中间表,中间表需要包含两张表的主键。
一对一:
定义:从表的一条记录对应主表的一条记录;
例子:员工信息表与身份证表、联系方式;
建表原则:这种对应关系的数据,通常放在单表里。
2.1多表及应用场景介绍多表就是在数据库设计中,使用多张表格来实现数据存储的要求;
在实际的项目开发中,数据量大而且复杂,需要分库分表;
分表:按照一定的规则,对原有的数据库和表进行拆分;
表与表之间可以通过外键建立连接。
2.2多表设计案例创建一张员工信息表,包含字段:
eid员工ID(自增主键)
ename员工姓名
age年龄
ger性别
dept_name所在部门
dept_id部门ID
dept_manager部门主管
dept_location所在地点
2.2.1以表单形式完成建表CREATETABLEemp(emp_idINTPRIMARYKEYAUTO_INCREMENT,enameVARCHAR(20),ageINT,gerVARCHAR(10),dept_nameVARCHAR(20),dept_idINT,dept_managerVARCHAR(20),dept_locationVARCHAR(20));2.2.2插入数据
INSERTINTOempVALUES(1,'张三',20,'男','研发部',1,'张无忌','北京');INSERTINTOemp(ename,age,ger,dept_name,dept_id,dept_manager,dept_location)VALUES('李四',25,'男','研发部',1,'张无忌','北京');INSERTINTOemp(ename,age,ger,dept_name,dept_id,dept_manager,dept_location)VALUES('宋江',40,'男','研发部',1,'张无忌','北京');INSERTINTOemp(ename,age,ger,dept_name,dept_id,dept_manager,dept_location)VALUES('林冲',25,'男','研发部',1,'张无忌','北京');INSERTINTOemp(ename,age,ger,dept_name,dept_id,dept_manager,dept_location)VALUES('林徽因',25,'女','研发部',1,'张无忌','北京');INSERTINTOemp(ename,age,ger,dept_name,dept_id,dept_manager,dept_location)VALUES('周芷若',25,'女','运营部',2,'赵敏','深圳');INSERTINTOemp(ename,age,ger,dept_name,dept_id,dept_manager,dept_location)VALUES('任盈盈',25,'女','运营部',2,'赵敏','深圳');2.2.3多表设计模式将数据拆分为员工信息表employee和部门信息表dept;
两个表之间通过部门id:dept_id字段连接。
创建部门表CREATETABLEdept(idINTPRIMARYKEYAUTO_INCREMENT,dept_nameVARCHAR(20),dept_managerVARCHAR(20),dept_locationVARCHAR(20));2.2.4插入数据
向员工信息表插入数据INSERTINTOemp_part(ename,age,ger,dept_id)VALUES('李四',25,'男',1);INSERTINTOemp_part(ename,age,ger,dept_id)VALUES('宋江',40,'男',1);INSERTINTOemp_part(ename,age,ger,dept_id)VALUES('张三',20,'男',1);INSERTINTOemp_part(ename,age,ger,dept_id)VALUES('林冲',25,'男',1);INSERTINTOemp_part(ename,age,ger,dept_id)VALUES('林徽因',25,'女',1);INSERTINTOemp_part(ename,age,ger,dept_id)VALUES('周芷若',25,'女',2);INSERTINTOemp_part(ename,age,ger,dept_id)VALUES('任盈盈',25,'女',2);三、SQL约束-外键约束3.1简介外键约束(FOREIGNKEY,缩写FK)是用来实现数据库表的参照完整性的。
它是指表中某个字段的值,依赖于另一张表中某个字段的值,而被依赖的字段必须且有主键约束或唯一约束。
被依赖的表,通常称之为父表或主表,设置外键约束的表称之为子表或从表。
3.2相关概念主键:可以唯一标识一条记录的列;
外键:从表中与主表的主键对应的字段;
主表:外键所指向的表,约束其他表的表;
从表:外键所在的表,被约束的表;
价值:建立主表与从表的关联关系,为两个表的数据建立连接,约束两个表中数据的一致性和完整性。
3.3建立外键约束创建表时添加外键约束:CONSTRAINT[外键约束的名称]FOREIGNKEY(外键字段)REFERENCES[主表名称](主表字段)
添加外键约束:ALTERTABLE[表名]ADDCONSTRAINT[外键约束的名称]FOREIGNKEY[外键字段]REFERENCES[主表名称(主键字段)]
插入一条非法数据INSERTINTOemp_partVALUES(1,'cindy',20,'female','4')3.4删除外键约束
语法:ALTERTABLE[表名]DROPFOREIGNKEY[外键约束名称]
注意事项:
从表外键数据类型必须与主表的主键一致;
删除数据时,需先删除从表数据,再删除主表数据;
添加数据时,先添加主表数据,再添加从表数据。
插入一条非法数据INSERTINTOemp_partVALUES(1,'cindy',20,'female','4')SELECT*FROMemp_part向从表中插入一条数据INSERTINTOemp_partVALUES(1,'cindy',20,'female','2')创建员工信息表并添加级联删除的外键约束CREATETABLEemp_part(emp_idINTPRIMARYKEYAUTO_INCREMENT,enameVARCHAR(20),ageINT,gerVARCHAR(10),dept_idINT,--添加外键约束CONSTRAINTemp_deptFOREIGNKEY(dept_id)REFERENCESdept(id)--设置允许级联删除ONDELETECASCADE);删除主表中部门id=2的部门DELETEFROMdeptWHEREid=2创建员工信息表并添加级联删除的外键约束CREATETABLEemp_part(emp_idINTPRIMARYKEYAUTO_INCREMENT,enameVARCHAR(20),ageINT,gerVARCHAR(10),dept_idINT,salaryINT,--添加外键约束CONSTRAINTemp_deptFOREIGNKEY(dept_id)REFERENCESdept(id)--设置允许级联删除ONDELETECASCADE);
向员工信息表中插入数据
INSERTINTOemp_partVALUES(1,'令狐冲',25,'男','1',20000);INSERTINTOemp_partVALUES(2,'任盈盈',23,'女','1',15000);INSERTINTOemp_partVALUES(3,'岳不群',45,'男','1',40000);INSERTINTOemp_partVALUES(4,'任我行',40,'男','1',30000);INSERTINTOemp_partVALUES(5,'岳灵珊',21,'女','1',10000);INSERTINTOemp_partVALUES(6,'赵灵儿',21,'女','2',7000);INSERTINTOemp_partVALUES(7,'林月如',22,'女','2',10000);INSERTINTOemp_partVALUES(8,'阿奴',20,'女','2',7000);INSERTINTOemp_partVALUES(9,'李逍遥',25,'男','2',15000);INSERTINTOemp_partVALUES(10,'景天',28,'男','2',20000);INSERTINTOemp_partVALUES(11,'邱莹莹',21,'女','3',5000);INSERTINTOemp_partVALUES(12,'关雎尔',22,'女','3',8000);INSERTINTOemp_partVALUES(13,'曲筱绡',23,'女','3',10000);INSERTINTOemp_partVALUES(14,'樊胜美',30,'女','3',10000);INSERTINTOemp_partVALUES(15,'安迪',28,'女','3',20000);五、多表查询-内连接查询5.1简介
内连接查询,也成为内连接或等值连接,是数据库查询中常见的查询方式。
内连接通过匹配两个或多个表的字段相等,来返回结果。
注意:内连接查询可以分为隐式内连接和显示内连接两种写法,但功能是一样的。
在查询的列出现二义性时,要使用完全限定名。
如果没有使用where子句过滤,则查询出的行数是两个数据表中的行数的乘积,这称之为“笛卡尔积”,会产生很多无用的数据。
5.2内连接内连接(INNERJOIN):将两个或多个表中满足条件的记录组合在一起,组成一个新的结果集。
内连接只返回两个表中都有的记录,即连接条件满足的记录。匹配显示,不匹配则不显示。
示例:比如使用外键=主键这个条件过滤掉无效数据。
按语法结构分为:隐式内连接和显示内连接。
5.2.1隐式内连接在笛卡尔积的基础上,使用where条件过滤无用的数据,这种连接方式是隐式内连接。
语法:select[字段名称]from表1,表2where[条件]
示例:
筛选出运营部的员工的id,姓名以及所在城市
SELECTemp_id,ename,dept_locationFROMemp_part,deptWHEREdept_id=idanddept_name="运营部";5.2.2显式内连接
语法:select[字段名称]from[表1]innerjoin[表2]on[条件]
示例:
查询运营部的员工id,姓名以及所在城市
SELECTemp_id,dept_location,enameFROMemp_partINNERJOINdeptONdept_id=idANDdept_name="运营部"六、多表查询-外连接查询6.1简介
多表查询中的外连接查询,是一种扩展了内连接查询的查询方式。
外连接查询在多表查询时,返回满足连接条件的所有行,以及左表中未找到匹配行的右表的所有行(左外连接),或右表中未找到匹配行的左表的所有行(右外连接)。
外连接通常用于查找相关联的数据,即使在某些表中没有匹配的行。
6.2外连接外连接查询:查询多个表中相关联的行,有时需要包含没有关联的行中数据,即返回查询结果集合中不仅包含符合连接条件的行,还包含左表(左连接)、右表(右连接)中的所有数据行。
左外连接:使用LEFTOUTERJOIN,其中OUTER可以省略。
右外连接:使用RIGHTOUTERJOIN,其中OUTER可以省略。
6.2.1左连接左连接:以左表为基准匹配右表的数据,右表中没有的项,显示为空。
语法:SELECT[字段]FROM[左表]LEFTJOIN[右表]ON[条件]
示例:公司新成立的人力资源部,还未招聘员工,请使用左连接方式查询出公司所有部门员工的id,姓名,性别以及他们所在的部门名称和城市。
查询出需要的数据SELECTemp_id,ename,ger,dept_name,dept_locationFROMdeptLEFTJOINemp_=emp__id6.2.2右连接
右连接:以右表为基准匹配左表的数据,左表中没有的项,显示为空。
语法:SELECT[字段]FROM[左表]RIGHTJOIN[右表]ON[条件]
示例:使用右连接方式查询所有部门员工的id,姓名,性别以及他们所在的部门名称和城市。
查询出需要的数据SELECTemp_id,ename,ger,dept_name,dept_locationFROMdeptRIGHTJOINemp_=emp__id七、子查询7.1简介
子查询:一个查询语句嵌套在另一个查询语句内部,在SELECT子句中先计算子查询,子查询的结果作为外层另一个查询的过滤条件,查询可以基于一个表或多个表。这个特性从开始引入。
子查询作为过滤条件时需要用()包裹。
7.2常见类型FROM型子查询:将子查询的结果作为付父查询的表来使用;
IN/NOTIN型子查询:子查询的结果是单列多行,作为where的过滤条件;
WHERE型子查询:查询结果作为过滤条件出现在比较运算符的一端。
7.2.1带FROM关键词的子查询子查询是一张多行多列的表,将子查询作为父查询的表来嵌套查询;
子查询语句必须用()包裹且需要有别名;
示例:计算出各部门性别为男性的员工人数。
selectdept_name,count(emp_id)from(selectdept_name,emp_id,ename,gerfromdeptinnerjoinemp_partwhereid=dept_idandger='男')bgroupbydept_name;7.2.2带IN关键词的子查询
将子查询作为WHERE语句后的过滤条件,常用于子查询结果是单列多行的情况。
子查询语句必须用()包裹且需要有别名;
示例:查询出北京地区所有的员工信息
SELECT*FROMemp_partWHEREdept_idIN(SELECTidFROMdeptWHEREdept_location='北京')7.2.3带比较运算符的子查询
将子查询的结果作为过滤条件,放在比较运算符的一端。
常用于子查询结果为单个结果的情况;
子查询语句必须用()包裹且需要有别名。
示例:
查询出部门平均薪资大于公司平均薪资的部门名称,部门主管,所在地及部门平均薪资使用withaswithdept_avgas(selectdept_id,avg(salary)avg_salaryfromemp_partgroupbydept_id)selectdept_id,dept_name,dept_manager,dept_location,avg_salaryfromdeptinnerjoindept_avgonid=dept_idandavg_salary(selectavg(avg_salary)fromdept_avg);





