数据库的多表关系:从入门到熟练

数据库的多表关系

阅读指南:

本文章讲述了对于数据库的多表关系,讲述了有哪些关系和这些关系是如何操作和维护的,如果读者感兴趣,后续我们会更新高级的操作在我们的对于数据库教程的合集中,大家可以来很我们一起学习讨论

合集链接:
数据库详细基础教程

数据库的多表关系及其维护

多表关系

多表关系的形成原因:

  • 由于在关系数据库中,数据都是按照类别存储到对应的表结构里面的,同时,表与表之间可以通过主外键来建立联系,所以拆表存储可以减少数据的冗余,并提高数据查询和操作的效率。

  • 又因为拆表存储的原因,我们不仅要掌握单表的查询语法,还需要掌握多表关联的查询语法。

  • 在关系数据库当中,需要提前创建库的结构,所以我们还需要通过分析数据关系在建表的时候添加合理的约束。

多表关系的情况:

  • 一对一:

两个表之间的每行数据都是唯一对应关系,例如:一个员工和其对应的员工档案。

  • 一对多:

一个表关联另一个表多行数据,反方向指关联一行数据。例如:一个作者与多篇文章。

  • 多对多:

两个表中的记录都可以与对方表中的多个记录相关联,例如:学生与课程之间的关系。

数据库多表关系的维护

一对一表关系

特点:

​ 双方的数据行都对应对方至少一条数据;

​ 容易产生冗余;

维护方式:

​ 外键唯一

​ 方案一: 子表的外键和主键融合,两张表公用同一个主键

​ 方案二: 对子表的外键添加唯一约束

示例:

sql 复制代码
# 一对一: 员工和档案表
CREATE TABLE emp(
    e_id  INT PRIMARY KEY AUTO_INCREMENT,
    e_name  VARCHAR(20) NOT NULL,  
    e_age  INT DEFAULT 18,
    e_gender  CHAR DEFAULT '男'
);

#方案1: 外键直接当主键
CREATE TABLE profile2(
    e_id  INT PRIMARY KEY,
    p_address VARCHAR(100) NOT NULL,  
    p_level  INT  DEFAULT 10,
    CONSTRAINT s_p_2  FOREIGN KEY(e_id) REFERENCES emp(e_id) 
);

#方案2: 正常存在外键,外键添加unique唯一约束
CREATE TABLE profile1(
    p_id  INT PRIMARY KEY AUTO_INCREMENT,
    p_address VARCHAR(100) NOT NULL,  
    p_level  INT  DEFAULT 10,
    e_id INT UNIQUE ,  # 外键唯一
    CONSTRAINT s_p_1  FOREIGN KEY(e_id) REFERENCES emp(e_id) 
);

一对多表关系

特点:

​ 主表对应多条子表数据,子表对应主表至多一条数据;

​ 可以解决数据的冗余问题;

维护方式:

​ 外键不唯一

​ 方法:正常的创建子表的外键约束即可,不用唯一就行

示例:

sql 复制代码
# 一对多: 作者和文章表

CREATE TABLE author(
    a_id  INT PRIMARY KEY AUTO_INCREMENT,
    a_name  VARCHAR(20) NOT NULL,  
    a_age  INT DEFAULT 18,
    a_gender  CHAR DEFAULT '男'
);

CREATE TABLE blog(
    b_id  INT PRIMARY KEY AUTO_INCREMENT,
    b_title VARCHAR(100) NOT NULL,  
    b_content VARCHAR(600) NOT NULL,  
    a_id INT ,  # 外键
    CONSTRAINT a_b_fk  FOREIGN KEY(a_id) REFERENCES author(a_id) 
);

多对多表关系

特点:

​ 双方数据行都可以对应对方的多条数据;

​ 多对多需要创建中间表建立数据之间的关联;

维护方式:

​ 中间表包含两个外键,主表数据之间间接关联

示例:

sql 复制代码
# 多对多: 学生和课程表
CREATE TABLE student(
    s_id  INT PRIMARY KEY AUTO_INCREMENT,
    s_name  VARCHAR(20) NOT NULL,  
    s_age  INT DEFAULT 18
);

# 中间表
CREATE TABLE student_course(
    sc_id  INT PRIMARY KEY AUTO_INCREMENT,
    s_id INT,  
    c_id  INT,
    FOREIGN KEY(s_id) REFERENCES student(s_id) ,
    FOREIGN KEY(c_id) REFERENCES course(c_id) 
);

CREATE TABLE course(
    c_id  INT PRIMARY KEY AUTO_INCREMENT,
    c_name VARCHAR(10) NOT NULL,  
    c_teacher  VARCHAR(10) 
);
相关推荐
微学AI15 分钟前
复杂时序场景的突围:金仓数据库是凭借什么超越InfluxDB?
数据库
小信啊啊17 分钟前
Go语言切片slice
开发语言·后端·golang
廋到被风吹走32 分钟前
【数据库】【Redis】定位、优势、场景与持久化机制解析
数据库·redis·缓存
有想法的py工程师2 小时前
PostgreSQL + Debezium CDC 踩坑总结
数据库·postgresql
Nandeska2 小时前
2、数据库的索引与底层数据结构
数据结构·数据库
Victor3562 小时前
Netty(20)如何实现基于Netty的WebSocket服务器?
后端
缘不易2 小时前
Springboot 整合JustAuth实现gitee授权登录
spring boot·后端·gitee
小卒过河01042 小时前
使用apache nifi 从数据库文件表路径拉取远程文件至远程服务器目的地址
运维·服务器·数据库
Kiri霧2 小时前
Range循环和切片
前端·后端·学习·golang
过期动态2 小时前
JDBC高级篇:优化、封装与事务全流程指南
android·java·开发语言·数据库·python·mysql