07 外键和表关联关系

文章目录

    • 外键约束
    • 表关联关系
    • E-R模型图
    • 表关联查询

外键约束

  • 约束 : 约束是一种限制,它通过对表的行或列的数据做出限制,来确保表的数据的完整性、关联性
  • foreign key 功能 : 建立表与表之间的某种约束的关系,由于这种关系的存在,能够让表与表之间的数据,更加的完整,关连性更强,为了具体说明创建如下部门表和人员表。
  • 示例
-- 创建部门表
CREATE TABLE dept (id int PRIMARY KEY auto_increment,dname VARCHAR(50) not null);

insert into dept values
(1,"技术部"),
(2,"销售部"),
(3,"市场部"),
(4,"行政部"),
(5,'财务部'),
(6,'总裁办公室');
-- 创建人员表
CREATE TABLE person (
  id int PRIMARY KEY AUTO_INCREMENT,
  name varchar(32) NOT NULL,
  age tinyint unsigned,
  salary decimal(8,2),
  dept_id int
) ;

insert into person values
(1,"Lily",29,20000,2),
(2,"Tom",27,16000,1),
(3,"Joy",30,28000,1),
(4,"Emma",24,8000,4),
(5,"Abby",28,17000,3),
(6,"Jame",32,22000,3);

上面两个表中每个人员都应该有指定的部门,但是实际上在没有约束的情况下人员是可以没有部门的或者也可以添加一个不存在的部门,这显然是不合理的。

  • 主表和从表:若同一个数据库中,B表的外键与A表的主键相对应,则A表为主表,B表为从表。

  • foreign key 外键的定义语法:

    [CONSTRAINT symbol] FOREIGN KEY(外键字段) 
    
    REFERENCES tbl_name (主表主键)
    
    [ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
    
    [ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}]
    
    

    该语法可以在 CREATE TABLE 和 ALTER TABLE 时使用

    -- 创建表时直接简历外键
    CREATE TABLE person (
    id int PRIMARY KEY AUTO_INCREMENT,
    name varchar(32) NOT NULL,
    age tinyint unsigned,
    salary decimal(10,2),
    dept_id int ,
    constraint dept_fk foreign key(dept_id) references dept(id)
    );
    

建立表后增加外键

alter table person add
constraint dept_fk
foreign key(dept_id)
references dept(id);

注意:

  1. 并不是任何情况表关系都需要建立外键来约束,如果没有类似上面的约束关系时也可以不建立。
  2. 从表的外键字段数据类型与指定的主表主键应该相同。
  • 通过外键名称解除外键约束

    alter table person drop foreign key dept_fk;
    
    -- 查看外键名称
    show create table person;
    

注意:删除外键后发现desc查看索引标志还在,其实外键也是一种索引,需要将外键名称的索引删除之后才可以。

  • 级联动作

    • restrict(默认) : on delete restrict on update restrict

      • 当主表删除记录时,如果从表中有相关联记录则不允许主表删除
      • 当主表更改主键字段值时,如果从表有相关记录则不允许更改
    • cascade :数据级联更新 on delete cascade on update cascade

      • 当主表删除记录或更改被参照字段的值时,从表会级联更新

        alter table person add
        constraint dept_fk
        foreign key(dept_id)
        references dept(id)
        on delete cascade on update cascade;
        
    • set null : on delete set null on update set null

      • 当主表删除记录时,从表外键字段值变为null

      • 当主表更改主键字段值时,从表外键字段值变为null

        alter table person add
        constraint dept_fk
        foreign key(dept_id)
        references dept(id)
        on delete set null on update set null;
        

表关联关系

当我们应对复杂的数据关系的时候,数据表的设计就显得尤为重要,认识数据之间的依赖关系是更加合理创建数据表关联性的前提。一对多和多对多是常见的表数据关系:

  • 一对多关系

一张表中有一条记录可以对应另外一张表中的多条记录;但是反过来,另外一张表的一条记录
只能对应第一张表的一条记录,这种关系就是一对多或多对一

举例: 一个人可以拥有多辆汽车,每辆车登记的车主只有一人。

create table person(
  id varchar(32) primary key,
  name varchar(30),
  age int
);

create table car(
  id varchar(32) primary key,
  brand varchar(30),
  price decimal(10,2),
  pid varchar(32),
  foreign key(pid) references person(id)
);

  • 多对多关系

一对表中(A)的一条记录能够对应另外一张表(B)中的多条记录;同时B表中的一条记录
也能对应A表中的多条记录

举例:一个运动员可以报多个项目,每个项目也会有多个运动员参加,这时为了表达多对多关系需要单独创建关系表。

CREATE TABLE athlete (
  id int primary key AUTO_INCREMENT,
  name varchar(30),
  age tinyint NOT NULL,
  country varchar(30) NOT NULL
);

CREATE TABLE item (
  id int primary key AUTO_INCREMENT,
  rname varchar(30) NOT NULL
);

CREATE TABLE athlete_item (
   id int primary key auto_increment,
   aid int NOT NULL,
   tid int NOT NULL,
   FOREIGN KEY (aid) REFERENCES athlete (id),
   FOREIGN KEY (tid) REFERENCES item (id)
);

-- 关系表中添加排名字段
alter table athlete_item add ranking int after tid;
表关系设计:
用户朋友圈表内容表:
姓名  密码  电话  图片 内容  地点 时间 点赞  评论

create table user(
id int primary key auto_increment,
name varchar(30),
passwd char(64),
tel char(16)
);

create table friends(
id int primary key auto_increment,
image char(50),
content varchar(1024),
time datetime ,
address varchar(50),
user_id int ,
foreign key(user_id) references user(id)
);

create table like_comment(
id int primary key auto_increment,
`like` bit,
comment text,
user_id int ,
friends_id int ,
foreign key(user_id) references user(id),
foreign key(friends_id) references friends(id)
);

E-R模型图

  • 定义
E-R模型(Entry-Relationship)即 实体-关系 数据模型,用于数据库设计
用简单的图(E-R图)反映了现实世界中存在的事物或数据以及他们之间的关系

  • 实体、属性、关系

​ 实体

1、描述客观事物的概念
2、表示方法 :矩形框
3、示例 :一个人、一本书、一杯咖啡、一个学生

​ 属性

1、实体具有的某种特性
2、表示方法 :椭圆形
3、示例
   学生属性 :学号、姓名、年龄、性别、专业 ... 
   感受属性 :悲伤、喜悦、刺激、愤怒 ...

​ 关系

1、实体之间的联系
2、一对多关联(1:n)
3、多对多关联(m:n) 

  • E-R图的绘制

矩形框代表实体,菱形框代表关系,椭圆形代表属性

er

表关系设计:
将book表拆分为三张表(图书   作家    出版社),自行设计表之间的关系,通过E-R图分析表关系和属性,然后写出创建语句

create table author(
id int primary key auto_increment,
name varchar(20),
sex char,
age tinyint
);

create table press(
id int primary key auto_increment,
pname varchar(20),
tel char(16),
address varchar(512)
);

create table book(
id char(18) primary key,
bname varchar(30),
price float,
author_id int,
press_id int ,
foreign key (author_id) references author(id),
foreign key (press_id) references press(id)
);

create table author_press(
id int primary key,
author_id int,
press_id int ,
foreign key (author_id) references author(id),
foreign key (press_id) references press(id)
);

表关联查询

如果多个表存在一定关联关系,可以多表在一起进行查询操作,其实表的关联整理与外键约束之间并没有必然联系,但是基于外键约束设计的具有关联性的表往往会更多使用关联查询查找数据。

  • 简单多表查询

多个表数据可以联合查询,语法格式如下:

select  字段1,字段2... from1,2... [where 条件]

e.g.
select c.name,c.score,h.hobby from class as c,hobby as h 
where c.name=h.name;

select name,salary,dname from person,dept
where person.dept_id = dept.id;

select name,salary,dname from person,dept 
where person.dept_id = dept.id and salary>=20000;

笛卡尔积现象就是将A表的每一条记录与B表的每一条记录强行拼在一起。所以,如果A表有n条记录,B表有m条记录,笛卡尔积产生的结果就会产生n*m条记录。

select * from class,hobby;
  • 内连接

内连接查询只会查找到符合条件的记录,其实结果和表关联查询是一样的,官方更推荐使用内连接查询。

inner

SELECT 字段列表
    FROM1  INNER JOIN2
ON1.字段 =2.字段;

select name,salary,dname from person inner join dept
on person.dept_id = dept.id
where salary>=20000;
  • 左连接 : 左表全部显示,显示右表中与左表匹配的项

left

SELECT 字段列表
    FROM1  LEFT JOIN2
ON1.字段 =2.字段;

e.g. 
select name,salary,dname
from person left join dept
on person.dept_id = dept.id
where salary>=20000;

-- 查询每个部门员工人数
select dname,count(name) from dept left join person on dept.id=person.dept_id group by dname;

  • 右连接 :右表全部显示,显示左表中与右表匹配的项
    right
SELECT 字段列表
    FROM1  RIGHT JOIN2
ON1.字段 =2.字段;

e.g.
select dname,count(name)
from person right join dept
on person.dept_id = dept.id
group by dname;

注意:我们尽量使用数据量大的表作为基准表,放在前面。


create table class(cid int primary key auto_increment,caption char(4) not null);
                  
create table teacher(tid int primary key auto_increment,tname varchar(32) not null);
                    
create table student(sid int primary key auto_increment,
                    sname varchar(32) not null,
                    gender enum('male','female','others') not null default 'male',
                    class_id int,
                    foreign key(class_id) references class(cid) 
                     on update cascade on delete cascade);
                    
create table course(cid int primary key auto_increment,
                   cname varchar(16) not null,
                   teacher_id int,
                   foreign key(teacher_id) references teacher(tid)
                    on update cascade on delete cascade);
                   
create table score(sid int primary key auto_increment,
                  student_id int,
                  course_id int,
                  number int(3) not null,
                  foreign key(student_id) references student(sid)
                   on update cascade on delete cascade,
                   foreign key(course_id) references course(cid)
                   on update cascade on delete cascade);
                   
insert into class(caption) values('三年一班'),('三年二班'),('三年三班');
insert into teacher(tname) values('魏老师'),('祁老师'),('小泽老师');
insert into student(sname,gender,class_id) values('钢蛋','female',1),('铁锤','female',1),('山炮','male',2),('彪哥','male',3),('虎子','male',3),('妞妞','female',2),('建国','male',2);
insert into course(cname,teacher_id) values('生物',1),('体育',1),('物理',2);
insert into score(student_id,course_id,number) values(1,1,60),(1,2,59),(2,2,100),(3,2,78),(4,3,66),(2,3,78),(5,2,77),(6,1,84),(7,1,79),(5,3,80),(3,1,59);

1. 查询每位老师教授的课程数量
2. 查询各科成绩最高和最低的分数,形式 : 课程ID  课程名称 最高分  最低分
3. 查询平均成绩大于85分的所有学生学号,姓名和平均成绩
4. 查询课程编号为2且课程成绩在80以上的学生学号和姓名
5. 查询各个课程及相应的选修人数
6. 查询每位学生的姓名,所在班级和各科平均成绩



1. 查询每位老师教授的课程数量
select tname,count(cname)
from teacher left join course
on teacher.tid = course.teacher_id
group by tname;

2. 查询各科成绩最高和最低的分数,形式 : 课程ID  课程名称 最高分  最低分
select cid as 课程ID,cname as 课程名称,
max(number) as 最高分,min(number) as 最低分
from course left join score
on course.cid = score.course_id
group by cid,cname;

3. 查询平均成绩大于85分的所有学生学号,姓名和平均成绩
select student.sid,sname,avg(number)
from student left join score
on student.sid = score.student_id
group by student.sid,sname
having avg(number) > 85;

4. 查询课程编号为2且课程成绩在80以上的学生学号和姓名
select student.sid,sname,number
from student left join score
on student.sid = score.student_id
where course_id=2 and number>80;

5. 查询各个课程及相应的选修人数
select cname,count(course_id)
from course left join score
on course.cid = score.course_id
group by cname;

6. 查询每位学生的姓名,所在班级和平均成绩
select sname,caption,avg(number)
from student left join class
on student.class_id = class.cid
left join score
on student.sid = score.student_id
group by sname,caption;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/433715.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

论文翻译:一种基于强化学习的车辆队列控制策略,用于减少交通振荡中的能量消耗

A Reinforcement Learning-Based Vehicle Platoon Control Strategy for Reducing Energy Consumption in Traffic Oscillations 一种基于强化学习的车辆队列控制策略,用于减少交通振荡中的能量消耗 文章目录 A Reinforcement Learning-Based Vehicle Platoon Cont…

基础50刷题之一(交替合并字符串)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、题目二、力扣官方题解(双指针)三、文心一言解释总结 前言 刚上研一,有人劝我好好学C,当时用的不多就没学&a…

快速上手:剧本杀dm预约平台小程序的制作流程

在当今的娱乐市场中,剧本杀已经成为一种备受欢迎的娱乐方式。为了给玩家提供更好的服务和体验,开发一个剧本杀DM预约平台小程序是至关重要的。下面,我们将详细介绍如何使用乔拓云第三方平台开发这样一个预约平台。 首先,打开乔拓云…

HarmonyOS 数据持久化之首选项 preferences

接下来 我们来说说数据持久化的问题 我们平时处理的数据都是在内存中处理的 我们应用一点重启 所有数据都消失了 肯恩是不符合一些场景的 harmonyos中 提供了比较多的解决方案 最多的两种是 用户首选项 关系型数据库 本文的话 我们就来看看 用户首选项 首先,什么…

Matlab在同一张图中如何加入多个图例

根据代码最终画出的图片如下: 其实原理很简单,就是在一张figure中画多个坐标轴,每个坐标轴都有对应的图例,之后再将多余坐标轴隐藏,只保留一个即可。 代码如下: clear all; close all;dd_linewidth 1;a …

VR全景数字工厂,制造业企业线上营销新助手

VR全景技术逐渐渗透到各行各业,其中,很多实体工厂的线上营销宣传也借助720云VR全景技术也迎来了新的变革。 一、VR全景技术的独特魅力 VR全景技术是一种基于虚拟现实技术的全新视觉呈现方式,能够为用户带来身临其境的沉浸式体验。通过VR全景…

Docker容器化解决方案(镜像,容器的操作管理)

Docker镜像管理 搜索官方仓库镜像 docker search [rootlocalhost ~]# docker search nginx NAME DESCRIPTION STARS OFFICIAL nginx Official build of Nginx. …

计算机mfc140.dll文件缺失的修复方法分析,一键修复mfc140.dll

电脑显示mfc140.dll文件缺失信息时,不必担心,这通常是个容易解决的小问题。接下来让我们详细探究并解决mfc140.dll文件缺失的状况。以下将详述相应的解决方案,从而帮助您轻松克服这一技术难题。通过几个简单步骤,即可恢复正常使用…

C语言项目实战——贪吃蛇

C语言实现贪吃蛇 前言一、 游戏背景二、游戏效果演示三、课程目标四、项目定位五、技术要点六、Win32 API介绍6.1 Win32 API6.2 控制台程序6.3 控制台屏幕上的坐标COORD6.4 GetStdHandle6.5 GetConsoleCursorInfo6.5.1 CONSOLE_CURSOR_INFO 6.6 SetConsoleCursorInfo6.7 SetCon…

LeetCode每日一题只 快乐数

目录 题目介绍: 算法原理: 鸽巢原理: 如何找到环里元素: 代码实现: 题目介绍: 题目链接:. - 力扣(LeetCode) 算法原理: 我先简单举两个例子&#xff…

python大数据分析游戏行业中的 Apache Kafka:用例 + 架构!

python大数据分析游戏行业中的 Apache Kafka:用例 架构! 这篇博文探讨了使用 Apache Kafka 的事件流如何提供可扩展、可靠且高效的基础设施,让游戏玩家开心并让游戏公司取得成功。讨论了游戏行业中的各种用例和架构,包括在线和移…

day04-SpringBootWeb入门

一、SpringBootWeb快速入门 1 需求 需求:基于 SpringBoot 的方式开发一个 web 应用,浏览器发起请求 /hello后,给浏览器返回字符串“Hello World ~”。 2 开发步骤 第1步:创建 SpringBoot 工程项目 第2步:定义 HelloC…

2024年k8s最新版本安装教程

k8s安装教程 1 k8s介绍2 环境搭建2.1 主机准备2.2 主机初始化2.2.1 安装wget2.2.2 更换yum源2.2.3 常用软件安装2.2.4 关闭防火墙2.2.5 关闭selinux2.2.6 关闭 swap2.2.7 同步时间2.2.8 修改Linux内核参数2.2.9 配置ipvs功能 2.3 容器安装2.3.1 设置软件yum源2.3.2 安装docker软…

Claude3、Gemini、Sora VS GPT-4:AI技术如何助力科研与产业发展?

【最新增加Claude3、Gemini、Sora、GPTs讲解及AI领域中的集中大模型的最新技术】 2023年随着OpenAI开发者大会的召开,最重磅更新当属GPTs,多模态API,未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义,不亚…

【Java EE】文件内容的读写⸺数据流

目录 🌴数据流的概念🌸数据流分类 🌳字节流的读写🌸InputStream(从文件中读取字节内容)🌻示例1🌻示例2🌻利用 Scanner 进行字符读取 🌸OutputStream(向文件中写内容&…

阿里云重新更新系统导致秘钥失效

报错解决方案: ssh-keygen -f "/Users/pengzhanliang/.ssh/known_hosts" -R "39.105.149.49"这个命令会从~/.ssh/known_hosts文件中移除与IP地址39.105.149.49相关的所有条目 再次尝试连接到远程服务器。这次,SSH将提示您接受新的主…

简单、透明、安全、高度集成!龙蜥可信 SBOM 能力探索与实践

近两年,软件供应链有非常多安全事件,包括软件供应链的各个阶段开发、构建、交付、使用等每个环节都有很多的软件供应链的安全事件发生。在 2023 龙蜥操作系统大会全面建设安全生态分论坛上,阿里云技术专家郑耿、周彭晨分享了龙蜥社区在构建 S…

企业计算机服务器中了faust勒索病毒怎么解密,faust勒索病毒解密流程

网络在为企业提供便利的同时,也为企业的数据安全问题带来严重威胁,网络安全是众多企业关系的主要话题,近期,云天数据恢复中心接到一大波企业的求助,企业的计算机服务器都被faust后缀勒索病毒攻击,导致企业计…

Electron 多显示器渲染

Electron打出的包,如果当前有俩个显示器,则可以配置当前显示倒哪个显示器上,或者可以配置不同的显示器,启动不同的项目,只在Windows和Linux下测试过,Mac没有真机,可以利用docker安装MacOS环境&a…

Jmeter性能测试 -3数据驱动实战

什么是数据驱动? 从数据文件中读取测试数据,驱动测试过程的一种测试方法。数据驱动可以理解为更高级的参数化。 特点:测试数据与测试代码分离;数据控制过程 好处:降低开发和维护成本,减少代码量&#xf…