关系型数据库中的关联关系与关联查询详解

发布于:2025-08-16 ⋅ 阅读:(19) ⋅ 点赞:(0)

目录

一、表与表的关联关系:数据连接的基石

1.1 一对一关系

1.2 一对多关系

1.3 多对多关系

1.4 自关联关系

二、关联查询:多表数据的联合提取​

2.1 内连接(INNER JOIN):取两表的交集

2.2 左连接(LEFT JOIN):保留左表全部记录

2.3 右连接(RIGHT JOIN):保留右表全部记录

2.4 全连接(FULL JOIN):保留两表全部记录

三、总结​


在关系型数据库(RDBMS)中,表与表之间的关联关系是数据组织的核心,而关联查询则是挖掘多表数据价值的关键技术。本文将系统解析数据库中常见的关联关系类型,详解关联查询的实现方式,并通过实例演示其在实际开发中的应用。

一、表与表的关联关系:数据连接的基石

        关联关系(Relationship)是指多个表之间通过共同字段建立的逻辑联系,其本质是通过外键(Foreign Key)实现数据的参照完整性。根据业务场景的不同,关联关系可分为以下四种类型:

1.1 一对一关系

定义:两个表中,A 表的一条记录仅对应 B 表的一条记录,反之亦然。​

特征:通常用于拆分字段较多的表(如将用户基本信息与详细信息分离),通过主键与外键关联(外键需添加唯一约束UNIQUE)。​

实例:

-- --一对一
CREATE TABLE user_info (
  user_id INT PRIMARY KEY not null AUTO_INCREMENT,
  username VARCHAR(50) NOT NULL UNIQUE,
  email VARCHAR(100) NOT NULL UNIQUE
);
INSERT INTO user_info (username, email) VALUES 
('zhangsan', 'zhangsan@qq.com'),
('lisi', 'lisi@qq.com');
CREATE TABLE user_profile (
  profile_id INT PRIMARY KEY AUTO_INCREMENT,
  user_id INT NOT NULL UNIQUE, 
  real_name VARCHAR(50),
  address VARCHAR(200),
  CONSTRAINT fk_profile_user FOREIGN KEY (user_id) 
  REFERENCES user_info (user_id) 
  ON DELETE CASCADE 
);

INSERT INTO user_profile (user_id, real_name, address) VALUES 
(1, '张三', '北京市海淀区'),
(2, '李四', '上海市浦东新区');

select user_id from user_info where username = "zhangsan";
select real_name from user_profile where user_id =(select user_id from user_info where username = "zhangsan")

1.2 一对多关系

定义:A 表的一条记录可对应 B 表的多条记录,但 B 表的一条记录仅对应 A 表的一条记录。​

特征:最常见的关联关系,通过 “一” 侧表的主键与 “多” 侧表的外键关联(外键无唯一约束)。​

实例:

-- 一对多
CREATE TABLE department (
  dept_id INT PRIMARY KEY AUTO_INCREMENT,
  dept_name VARCHAR(50) NOT NULL UNIQUE,
  location VARCHAR(100)
);
INSERT INTO department (dept_name, location) VALUES 
('研发部', '办公楼A座'),
('市场部', '办公楼B座');
CREATE TABLE employee (
  emp_id INT PRIMARY KEY AUTO_INCREMENT,
  emp_name VARCHAR(50) NOT NULL,
  dept_id INT, 
  salary DECIMAL(10,2),
-- 
  CONSTRAINT fk_emp_dept FOREIGN KEY (dept_id) 
  REFERENCES department (dept_id) 
  ON DELETE SET NULL  
);
INSERT INTO employee (emp_name, dept_id, salary) VALUES 
('zs', 1, 8000),
('ls', 1, 9000),
('ww', 2, 7500);
--
SELECT d.dept_name, e.emp_name, e.salary 
FROM `department` d
JOIN `employee` e ON d.dept_id = e.dept_id
WHERE d.dept_name = '研发部';

1.3 多对多关系

定义:A 表的一条记录可对应 B 表的多条记录,反之 B 表的一条记录也可对应 A 表的多条记录。​

特征:需通过 “中间表” 实现关联,中间表包含两个外键,分别关联两个表的主键。​

实例:

-- 多对多
CREATE TABLE products (
    product_id INT PRIMARY KEY AUTO_INCREMENT,
    product_name VARCHAR(100) NOT NULL,
    price DECIMAL(10,2) NOT NULL
);
INSERT INTO products (product_name, price) VALUES
('笔记本电脑', 5999.99),
('机械键盘', 299.99),
('鼠标', 99.99),
('耳机', 799.99);
CREATE TABLE orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    order_number VARCHAR(50) NOT NULL UNIQUE, 
    customer_name VARCHAR(50) NOT NULL
);
INSERT INTO orders (order_number, customer_name) VALUES
('ORD2023001', '张三'),
('ORD2023002', '李四');
CREATE TABLE order_products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    order_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT NOT NULL, 
    unit_price DECIMAL(10,2) NOT NULL, 
    CONSTRAINT fk_order 
    FOREIGN KEY (order_id) 
    REFERENCES orders(order_id)
    ON DELETE CASCADE,
    CONSTRAINT fk_product 
    FOREIGN KEY (product_id) 
    REFERENCES products(product_id)
    ON DELETE CASCADE,
    
    UNIQUE KEY uk_order_product (order_id, product_id)
);
INSERT INTO order_products (order_id, product_id, quantity, unit_price) VALUES
(1, 1, 1, 5999.99), 
(1, 2, 1, 299.99),
(1, 3, 1, 99.99),  
(2, 2, 2, 299.99),  
(2, 4, 1, 799.99);
SELECT o.order_number,p.product_name,op.quantity FROM orders o
JOIN order_products op ON o.order_id = op.order_id
JOIN products p ON op.product_id = p.product_id
WHERE o.order_number = 'ORD2023001';

1.4 自关联关系

定义:表中的字段关联同表中的其他字段,用于表示层级或递归关系。​

特征:外键指向自身表的主键,常用于构建树形结构(如组织架构、评论回复)。​

实例:

-- --自关联
CREATE TABLE person (
    id INT NOT NULL AUTO_INCREMENT,
    name VARCHAR(10) NOT NULL,
    parent_id INT,
    PRIMARY KEY (id),
    FOREIGN KEY (parent_id) REFERENCES person(id)  
);
INSERT INTO `teacher`.`person`(`id`, `name`, `parent_id`) VALUES (1, 'p1', NULL);
INSERT INTO `teacher`.`person`(`id`, `name`, `parent_id`) VALUES (2, ' p2', NULL);
INSERT INTO `teacher`.`person`(`id`, `name`, `parent_id`) VALUES (3, 'p11', 1);
INSERT INTO `teacher`.`person`(`id`, `name`, `parent_id`) VALUES (4, ' p12', 1);
INSERT INTO `teacher`.`person`(`id`, `name`, `parent_id`) VALUES (5, 'p21', 2);
INSERT INTO `teacher`.`person`(`id`, `name`, `parent_id`) VALUES (6, ' p22', 2);

二、关联查询:多表数据的联合提取​

        关联查询(Join Query)是通过关联条件将多个表的记录组合起来的查询方式,核心是使用JOIN关键字连接表,并通过ON子句指定关联条件。根据对 “不匹配记录” 的处理方式,关联查询可分为以下四类:

2.1 内连接(INNER JOIN):取两表的交集

作用:仅返回两个表中满足关联条件的记录(即 “匹配的交集”)。

实例:

CREATE TABLE light(id INT NOT NULL auto_increment PRIMARY KEY,
name VARCHAR(20) NOT NULL,
size INT NOT NULL DEFAULT 1.2,
des VARCHAR(500)
);

INSERT INTO light (name,size,des) VALUES 
("长灯",1.5,NULL),
("长条吸顶灯",2.0,NULL),
("日光灯管",1.2,NULL),
("长灯",1.5,NULL),
("景观长灯",1.3,NULL),
("日光灯管",1.6,NULL);

CREATE TABLE light_category (
    category_id INT PRIMARY KEY AUTO_INCREMENT,
    category_name VARCHAR(50) NOT NULL, 
    description VARCHAR(200) 
);

ALTER TABLE light 
ADD COLUMN category_id INT,
ADD CONSTRAINT fk_light_category 
FOREIGN KEY (category_id) REFERENCES light_category(category_id);

INSERT INTO light_category (category_name, description) VALUES
('家居长灯', '家庭使用的长条形灯具'),
('商用长灯', '公共场所使用的长条形灯具'),
('户外长灯', '室外环境使用的长条形灯具');

select l.id,l.name,l.size,c.category_name from  light l inner join light_category c on l.category_id = c.category_id;

2.2 左连接(LEFT JOIN):保留左表全部记录

作用:返回左表的所有记录,以及右表中满足关联条件的记录(右表无匹配则显示NULL)。

实例:

select l.id,l.name,l.size,c.category_name from  light l left join light_category c on l.category_id = c.category_id;

2.3 右连接(RIGHT JOIN):保留右表全部记录

作用:返回右表的所有记录,以及左表中满足关联条件的记录(左表无匹配则显示NULL)。

实例:

select l.id,l.name,l.size,c.category_name from  light l right join light_category c on l.category_id = c.category_id;

2.4 全连接(FULL JOIN):保留两表全部记录

作用:返回左表和右表的所有记录,两表中无匹配的部分均显示NULL。

说明:MySQL 不直接支持FULL JOIN,需通过LEFT JOIN与RIGHT JOIN的结果联合(UNION)实现。

select l.id,l.name,l.size,c.category_name from  light l left join light_category c on l.category_id = c.category_id and select l.id,l.name,l.size,c.category_name from  light l right join light_category c on l.category_id = c.category_id;

三、总结​

        关联关系是关系型数据库的核心设计思想,一对一、一对多、多对多和自引用关系分别对应不同的业务场景,其中一对多和多对多最为常见(多对多需通过中间表实现)。​

        关联查询通过INNER JOIN、LEFT JOIN等方式实现多表数据的联合提取,关键是明确 “保留哪些表的记录” 以及 “如何关联字段”。在实际开发中,需根据业务需求选择合适的关联类型,并通过索引优化、条件筛选等方式提升查询性能。​

掌握关联关系设计与关联查询技巧,是构建高效、清晰的数据库系统的基础,也是处理复杂业务数据的必备能力。


网站公告

今日签到

点亮在社区的每一天
去签到