数据库的多表关系
阅读指南:
本文章讲述了对于数据库的多表关系,讲述了有哪些关系和这些关系是如何操作和维护的,如果读者感兴趣,后续我们会更新高级的操作在我们的对于数据库教程的合集中,大家可以来很我们一起学习讨论
合集链接:
数据库详细基础教程
数据库的多表关系及其维护
多表关系
多表关系的形成原因:
-
由于在关系数据库中,数据都是按照类别存储到对应的表结构里面的,同时,表与表之间可以通过主外键来建立联系,所以拆表存储可以减少数据的冗余,并提高数据查询和操作的效率。
-
又因为拆表存储的原因,我们不仅要掌握单表的查询语法,还需要掌握多表关联的查询语法。
-
在关系数据库当中,需要提前创建库的结构,所以我们还需要通过分析数据关系在建表的时候添加合理的约束。
多表关系的情况:
- 一对一:
两个表之间的每行数据都是唯一对应关系,例如:一个员工和其对应的员工档案。
- 一对多:
一个表关联另一个表多行数据,反方向指关联一行数据。例如:一个作者与多篇文章。
- 多对多:
两个表中的记录都可以与对方表中的多个记录相关联,例如:学生与课程之间的关系。
数据库多表关系的维护
一对一表关系
特点:
双方的数据行都对应对方至少一条数据;
容易产生冗余;
维护方式:
外键唯一
方案一: 子表的外键和主键融合,两张表公用同一个主键
方案二: 对子表的外键添加唯一约束
示例:
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)
);