Skip to content

多表关系


在关系型数据库中(如 MySQL、Oracle),多表关系指的是不同数据表之间通过**字段关联(主键/外键)**形成的逻辑联系。
这就像现实世界中「人 → 部门」「订单 → 商品」「学生 → 课程」等之间的关系。

多表关系 = 数据库中“对象与对象之间”的关系。

数据库中的多表关系主要有三种:

类型英文关系举例数据库设计方式
一对一One-to-One人 ↔ 身份证在任意一方加外键并唯一约束
一对多One-to-Many部门 ↔ 员工在“多”的那一方加外键
多对多Many-to-Many学生 ↔ 课程通过“中间表”实现

概念:

一个表中的一条记录,只能对应另一个表中的一条记录。

例如:

  • 一个用户对应一个身份证信息

  • 一个公司对应一个公司资质文件

CREATE TABLE user (
id BIGINT PRIMARY KEY,
name VARCHAR(50),
gender CHAR(1)
);
CREATE TABLE user_idcard (
id BIGINT PRIMARY KEY,
user_id BIGINT UNIQUE, -- 唯一外键,确保一对一
id_number VARCHAR(18),
FOREIGN KEY (user_id) REFERENCES user(id)
);

常用场景:

  • 一般用于将表拆分(垂直分表),如将敏感信息独立存储;

  • 性能或安全性考虑时常见(例如用户基本信息与隐私信息分开)。

概念:

一个表的某条记录可以对应另一个表的多条记录。

例如:

  • 一个部门下有多个员工

  • 一个小区下有多栋楼栋

CREATE TABLE department (
id BIGINT PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE employee (
id BIGINT PRIMARY KEY,
name VARCHAR(50),
department_id BIGINT, -- 外键,指向部门
FOREIGN KEY (department_id) REFERENCES department(id)
);

常用场景:

  • 这是最常见的关系;

  • 查询时常用 JOIN,如:

    SELECT e.name, d.name AS dept_name
    FROM employee e
    LEFT JOIN department d ON e.department_id = d.id;

概念:

一个表中的一条记录可以对应另一个表的多条记录,反之亦然。

例如:

  • 学生可以选多门课,一门课也可以有多个学生;

  • 用户可以有多个角色,一个角色也可以分配给多个用户。

CREATE TABLE student (
id BIGINT PRIMARY KEY,
name VARCHAR(50)
);
CREATE TABLE course (
id BIGINT PRIMARY KEY,
name VARCHAR(50)
);
-- 中间表(关联表)
CREATE TABLE student_course (
student_id BIGINT,
course_id BIGINT,
PRIMARY KEY (student_id, course_id),
FOREIGN KEY (student_id) REFERENCES student(id),
FOREIGN KEY (course_id) REFERENCES course(id)
);

常用场景:

  • 通过“中间表”实现多对多;

  • 在业务层通常会封装为“一对多 + 一对多”来处理;

  • ORM 框架(如 MyBatis-Plus)中可通过中间表映射实现。

  1. 命名规范

    • 外键字段通常命名为:xxx_id

    • 中间表命名为:表A_表B(如 student_course

  2. 数据完整性

    • 使用 FOREIGN KEY 确保关系一致;

    • 若性能要求高,可在程序层控制外键逻辑,避免数据库级约束。

  3. 索引优化

    • 外键列应建索引;

    • 中间表的复合主键 (a_id, b_id) 通常也是索引。

  4. ORM 映射建议

    • 一对一:@OneToOne

    • 一对多:@OneToMany + @ManyToOne

    • 多对多:@ManyToMany + @JoinTable