MySQL - 数据库设计(表之间的 3 种关联关系)

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL - 数据库设计(表之间的 3 种关联关系)

表与表之间一般存在三种关系,即一对一,一对多,多对多关系。

下面分别就三种关系讲解数据库相关设计的思路和思考过程。

 

一、一对一关系

例如,下面的一张表,保存了人的相关信息,有男有女,要求查处所有的夫妻。

sql代码:

CREATETABLEIFNOTEXISTSperson(
idINTPRIMARYKEYAUTO_INCREMENT,
snameVARCHAR(10),
sexCHAR(1),
husbandINT,
wifeINT);
INSERTINTOpersonVALUES(1,'小花','0',3,0);
INSERTINTOpersonVALUES(2,'小明','1',0,4);
INSERTINTOpersonVALUES(3,'张三','1',0,1);
INSERTINTOpersonVALUES(4,'小丽','0',2,0);
INSERTINTOpersonVALUES(5,'王五','1',0,0);

sql代码对应的person表:

image.png

从表中可以看出,小花和张三是夫妻,小明和小丽是夫妻。通常为了查询方便,需要两个表,但实际项目中为了省空间,通常只建一个表,要实现一对一查询,可以建立两个视图(虚表)

* 有个小细节提一下,视图只是个逻辑概念,并不独立占用物理内存,它依附于数据表,对视图进行修改时相应的表数据也会盖改动 *

CREATEVIEWmenAS (SELECT*FROMpersonWHEREsex='1');
CREATEVIEWwomenAS (SELECT*FROMpersonWHEREsex='0');

men视图:

image.png

women视图:

image.png

执行查询:

方式一(原始方法)

SELECTmen.snameAShusband,women.snameASwifeFROMmen,womenWHEREmen.id=women.husbandANDwomen.id=men.wife;

方式二(连接方法)

SELECTmen.snameAShusband,women.snameASwifeFROMmenINNERJOINwomenONmen.id=women.husbandANDwomen.id=men.wife;

二、一对多关系

例如:一个人可以拥有多辆汽车,要求查询某个人拥有的所有车辆。


分析:这种情况其实也可以采用 一张表,但因为一个人可以拥有多辆汽车,如果采用一张表,会造成冗余信息过多。好的设计方式是,人和车辆分别单独建表,那么如何将两个表关联呢?有个巧妙的方法,在车辆的表中加个外键字段(人的编号)即可。

* (思路小结:’建两个表,一’方不动,’多’方添加一个外键字段) *

sql代码:

// 建立人员表
CREATETABLE human(    id VARCHAR(12) PRIMARY KEY,    sname VARCHAR(12),    age INT,    sex CHAR(1));INSERTINTO human VALUES('H001','小王',27,'1');INSERTINTO human VALUES('H002','小明',24,'1');INSERTINTO human VALUES('H003','张慧',28,'0');INSERTINTO human VALUES('H004','李小燕',35,'0');INSERTINTO human VALUES('H005','王大拿',29,'1');INSERTINTO human VALUES('H006','周强',36,'1');// 建立车辆信息表
CREATETABLE car(    id VARCHAR(12) PRIMARY KEY,    mark VARCHAR(24),    price NUMERIC(6,2),    hid VARCHAR(12),    CONSTRAINT fk_human FOREIGN KEY(hid) REFERENCES human(id));INSERTINTO car VALUES('C001','BMW',65.99,'H001');INSERTINTO car VALUES('C002','BenZ',75.99,'H002');INSERTINTO car VALUES('C003','Skoda',23.99,'H001');INSERTINTO car VALUES('C004','Peugeot',20.99,'H003');INSERTINTO car VALUES('C005','Porsche',295.99,'H004');INSERTINTO car VALUES('C006','Honda',24.99,'H005');INSERTINTO car VALUES('C007','Toyota',27.99,'H006');INSERTINTO car VALUES('C008','Kia',18.99,'H002');INSERTINTO car VALUES('C009','Bentley',309.99,'H005');

sql代码对应的人员表:

image.png

sql代码对应的车辆信息表:

image.png

执行查询

SELECT human.sname AS 车主,car.mark AS 车辆 FROM human,car WHERE human.id = car.hid;
SELECT human.sname AS 车主,car.mark AS 车辆 FROM human INNER JOIN car WHERE human.id = car.hid;

三、多对多关系

例如:学生选课,一个学生可以选修多门课程,每门课程可供多个学生选择。

分析:这种方式可以按照类似一对多方式建表,但冗余信息太多,好的方式是实体和关系分离并单独建表,实体表为学生表和课程表,关系表为选修表,其中关系表采用联合主键的方式(由学生表主键和课程表主键组成)建表。

sql代码:

// 建立学生表
CREATETABLE student(    id VARCHAR(10) PRIMARY KEY,    sname VARCHAR(12),    age INT,    sex CHAR(1),    class VARCHAR(6));INSERTINTO student VALUES('S0001','王军',20,1,'c101');INSERTINTO student VALUES('S0002','张宇',21,1,'c101');INSERTINTO student VALUES('S0003','刘飞',22,1,'c102');INSERTINTO student VALUES('S0004','赵燕',18,0,'c103');INSERTINTO student VALUES('S0005','曾婷',19,0,'c103');INSERTINTO student VALUES('S0006','周慧',21,0,'c104');INSERTINTO student VALUES('S0007','小红',23,0,'c104');INSERTINTO student VALUES('S0008','杨晓',18,0,'c104');INSERTINTO student VALUES('S0009','李杰',20,1,'c105');INSERTINTO student VALUES('S0010','张良',22,1,'c105');// 建立课程表
CREATETABLE course(    id VARCHAR(10) PRIMARY KEY,    sname VARCHAR(12),    credit NUMERIC(2,1),    teacher VARCHAR(12));INSERTINTO course VALUES('C001','Java',3.5,'李老师');INSERTINTO course VALUES('C002','高等数学',5.0,'赵老师');INSERTINTO course VALUES('C003','JavaScript',3.5,'王老师');INSERTINTO course VALUES('C004','离散数学',3.5,'卜老师');INSERTINTO course VALUES('C005','数据库',3.5,'廖老师');INSERTINTO course VALUES('C006','操作系统',3.5,'张老师');// 建立选修表
CREATETABLE sc(    sid VARCHAR(10),    cid VARCHAR(10));ALTERTABLE sc ADD CONSTRAINT pk_sc PRIMARY KEY(sid,cid);ALTERTABLE sc ADD CONSTRAINT fk_student FOREIGN KEY(sid) REFERENCES student(id);ALTERTABLE sc ADD CONSTRAINT fk_course FOREIGN KEY(cid) REFERENCES course(id);INSERTINTO sc VALUES('S0001','C001');INSERTINTO sc VALUES('S0001','C002');INSERTINTO sc VALUES('S0001','C003');INSERTINTO sc VALUES('S0002','C001');INSERTINTO sc VALUES('S0002','C004');INSERTINTO sc VALUES('S0003','C002');INSERTINTO sc VALUES('S0003','C005');INSERTINTO sc VALUES('S0004','C003');INSERTINTO sc VALUES('S0005','C001');INSERTINTO sc VALUES('S0006','C004');INSERTINTO sc VALUES('S0007','C002');INSERTINTO sc VALUES('S0008','C003');INSERTINTO sc VALUES('S0009','C001');INSERTINTO sc VALUES('S0009','C005');

sql代码对应的学生表:

image.png

sql代码对应的课程表:

image.png

sql代码对应的选课表:

image.png

执行查询:(没有选课的学生信息和无学生选的课程信息)

普通方式:

SELECT * FROM student WHERE student.id NOT IN (SELECT sid FROM sc);
SELECT * FROM course WHERE course.id NOT IN (SELECT cid FROM sc);

关联方式:

SELECT student.* FROM student LEFT JOIN sc ON student.id=sc.sid LEFT JOIN course ON course.id = sc.cid WHERE course.sname IS NULL;
SELECT course.* FROM course LEFT JOIN sc ON course.id=sc.cid LEFT JOIN student ON student.id = sc.sid WHERE student.sname IS NULL;


转自:https://blog.csdn.net/lengjinghk/article/details/52140276


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
目录
相关文章
|
3月前
|
人工智能 运维 关系型数据库
数据库运维:mysql 数据库迁移方法-mysqldump
本文介绍了MySQL数据库迁移的方法与技巧,重点探讨了数据量大小对迁移方式的影响。对于10GB以下的小型数据库,推荐使用mysqldump进行逻辑导出和source导入;10GB以上可考虑mydumper与myloader工具;100GB以上则建议物理迁移。文中还提供了统计数据库及表空间大小的SQL语句,并讲解了如何使用mysqldump导出存储过程、函数和数据结构。通过结合实际应用场景选择合适的工具与方法,可实现高效的数据迁移。
601 1
|
4月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
3月前
|
SQL 关系型数据库 MySQL
Go语言数据库编程:使用 `database/sql` 与 MySQL/PostgreSQL
Go语言通过`database/sql`标准库提供统一数据库操作接口,支持MySQL、PostgreSQL等多种数据库。本文介绍了驱动安装、连接数据库、基本增删改查操作、预处理语句、事务处理及错误管理等内容,涵盖实际开发中常用的技巧与注意事项,适合快速掌握Go语言数据库编程基础。
218 62
|
2月前
|
SQL 存储 关系型数据库
MySQL功能模块探秘:数据库世界的奇妙之旅
]带你轻松愉快地探索MySQL 8.4.5的核心功能模块,从SQL引擎到存储引擎,从复制机制到插件系统,让你在欢声笑语中掌握数据库的精髓!
|
2月前
|
SQL Oracle 关系型数据库
比较MySQL和Oracle数据库系统,特别是在进行分页查询的方法上的不同
两者的性能差异将取决于数据量大小、索引优化、查询设计以及具体版本的数据库服务器。考虑硬件资源、数据库设计和具体需求对于实现优化的分页查询至关重要。开发者和数据库管理员需要根据自身使用的具体数据库系统版本和环境,选择最合适的分页机制,并进行必要的性能调优来满足应用需求。
88 11
|
2月前
|
SQL 关系型数据库 MySQL
【赵渝强老师】MySQL中的数据库对象
本教程详细介绍了MySQL数据库中的常见对象,包括表、索引、视图、事件、存储过程和存储函数的创建与管理。内容涵盖表的基本操作、索引的使用、视图简化查询、事件调度功能等,并通过具体示例演示相关SQL语句的使用方法。
|
4月前
|
存储 关系型数据库 MySQL
大数据新视界 --面向数据分析师的大数据大厂之 MySQL 基础秘籍:轻松创建数据库与表,踏入大数据殿堂
本文详细介绍了在 MySQL 中创建数据库和表的方法。包括安装 MySQL、用命令行和图形化工具创建数据库、选择数据库、创建表(含数据类型介绍与选择建议、案例分析、最佳实践与注意事项)以及查看数据库和表的内容。文章专业、严谨且具可操作性,对数据管理有实际帮助。
大数据新视界 --面向数据分析师的大数据大厂之 MySQL 基础秘籍:轻松创建数据库与表,踏入大数据殿堂
|
4月前
|
SQL 关系型数据库 MySQL
MySQL下载安装全攻略!小白也能轻松上手,从此数据库不再难搞!
这是一份详细的MySQL安装与配置教程,适合初学者快速上手。内容涵盖从下载到安装的每一步操作,包括选择版本、设置路径、配置端口及密码等。同时提供基础操作指南,如数据库管理、数据表增删改查、用户权限设置等。还介绍了备份恢复、图形化工具使用和性能优化技巧,帮助用户全面掌握MySQL的使用方法。附带常见问题解决方法,保姆级教学让你无忧入门!
MySQL下载安装全攻略!小白也能轻松上手,从此数据库不再难搞!
|
4月前
|
关系型数据库 MySQL 定位技术
MySQL与Clickhouse数据库:探讨日期和时间的加法运算。
这一次的冒险就到这儿,期待你的再次加入,我们一起在数据库的世界中找寻下一个宝藏。
181 9
|
4月前
|
存储 关系型数据库 MySQL
【赵渝强老师】OceanBase数据库从零开始:MySQL模式
《OceanBase数据库从零开始:MySQL模式》是一门包含11章的课程,涵盖OceanBase分布式数据库的核心内容。从体系架构、安装部署到租户管理、用户安全,再到数据库对象操作、事务与锁机制,以及应用程序开发、备份恢复、数据迁移等方面进行详细讲解。此外,还涉及连接路由管理和监控诊断等高级主题,帮助学员全面掌握OceanBase数据库的使用与管理。
256 5

热门文章

最新文章

推荐镜像

更多