Skip to content

SQL 表关系详解

深入剖析数据库中的一对一、一对多、多对多关系及实现

一对一关系 (One-to-One)

             **定义:** 表 A 中的一条记录只能对应表 B 中的一条记录,反之亦然。常用于拆分宽表以提升性能或安全性。
sql
-- 方式一:共享主键 (Profile.id 即是 PK 也是 FK)
CREATE TABLE user_profile (
    user_id INT PRIMARY KEY,
    address VARCHAR(200),
    FOREIGN KEY (user_id) REFERENCES user(id)
);

-- 方式二:独立外键 (需加 UNIQUE 约束)
CREATE TABLE user_detail (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT UNIQUE, -- 关键:Unique 保证 1对1
    FOREIGN KEY (user_id) REFERENCES user(id)
);
  • 必须在其中一个表的外键列上添加 UNIQUE 约束(方式二)。

  • 常用于垂直分表:将高频访问字段和低频大字段(如自我介绍)分离。

  • 两种方式均能保证数据一致性,共享主键方式更节省空间。

一对多关系 (One-to-Many)

             **定义:** 最常见的关系。A 表一条记录对应 B 表多条记录,但 B 表一条记录仅对应 A 表一条。
sql
-- 1. 创建"一"的一方 (销售员)
CREATE TABLE salesperson (
    id INT PRIMARY KEY,
    name VARCHAR(50)
);

-- 2. 创建"多"的一方 (订单),添加外键指向"一"
CREATE TABLE orders (
    id INT PRIMARY KEY,
    amount DECIMAL(10, 2),
    salesperson_id INT,
    FOREIGN KEY (salesperson_id) REFERENCES salesperson(id)
);
  • 原则:在"多"的一方维护外键。

  • 如果业务上允许订单没有归属,外键可以设置为 NULL。

多对多关系 (Many-to-Many)

             **定义:** A 表记录对应多个 B 表记录,反之亦然。例如:学生与课程、文章与标签。
sql
-- 需要通过"中间表"来解耦
CREATE TABLE student_course (
    student_id INT,
    course_id INT,
    PRIMARY KEY (student_id, course_id), -- 联合主键
    FOREIGN KEY (student_id) REFERENCES student(id),
    FOREIGN KEY (course_id) REFERENCES course(id)
);
  • 必须引入第三张表(关联表/中间表)。

  • 中间表可以包含额外属性,例如:选课时间、考试成绩。

  • 联合主键可防止重复关联相同的数据(如同一学生重复选同一课)。

关系模型总结

                    关系类型
                    实现核心
                    典型场景
                
            
            
                
                    一对多 (1:N)
                    在 N 端加外键
                    用户-订单,部门-员工,分类-商品
                
                
                    一对一 (1:1)
                    外键加 UNIQUE 约束
                    用户-身份证信息,主表-扩展表
                
                
                    多对多 (N:M)
                    中间表 + 双外键
                    学生-课程,角色-权限,作者-书籍

进阶:物理外键 vs 逻辑外键

数据库设计中的经典权衡:是依赖数据库约束,还是依赖代码逻辑?

                    特性
                    物理外键 (DBMS Constraint)
                    逻辑外键 (Application Logic)
                
            
            
                
                     **数据完整性** 
                    极高 - 数据库强制保证,杜绝脏数据
                    中等 - 依赖代码健壮性,Bug可能导致数据不一致
                
                
                     **写入性能** 
                    略低 - 插入/删除时需检查约束,有锁开销
                    高 - 无额外数据库检查开销
                
                
                     **架构耦合** 
                    高 - 分库分表困难,难以水平扩展
                    低 - 适合分布式架构和微服务
                
                
                     **级联操作** 
                    支持 (Cascade Delete/Update)
                    需手动编写代码逻辑处理
                
                
                     **推荐场景** 
                     **传统单体应用、数据敏感、后台管理系统** 
                     **互联网高并发、分库分表、微服务架构** 

附录:主流数据库类型速查

不同数据库在实现相同概念时,数据类型名称往往不同。

                    类型
                    MySQL
                    Oracle
                    SQL Server
                
            
            
                
                     **变长字符串** 
                     `VARCHAR(N)` 
                     `VARCHAR2(N)` 
                     `VARCHAR(N)` 
                
                
                     **时间日期** 
                     `DATETIME` 
                     `DATE`  (含时分秒)
                     `DATETIME2` 
                
                
                     **大整数** 
                     `BIGINT` 
                     `NUMBER(19)` 
                     `BIGINT` 
                
                
                     **自动增长** 
                     `AUTO_INCREMENT` 
                     `SEQUENCE` 
                     `IDENTITY`

基于 VitePress 构建 | 技术知识库