关联关系查询
概述
关联关系查询允许您在单个请求中获取多个相关表的数据,避免多次查询的性能开销。系统通过 MySQL 外键约束自动识别表间关系。
基本概念
- 主表:外键字段所在的表,是关联关系中的「多方」
- 从表:被关联的表,通过主键与主表的外键建立关系
- 关联方式:支持外关联(LEFT JOIN)和内关联(INNER JOIN)
查询语法
关联方式
| 关联方式 | 语法 | 说明 | SQL 等价 |
|---|---|---|---|
| 外关联 | 关联字段(子字段1,子字段2) | 默认使用 LEFT JOIN,即使关联表无数据也会返回主表记录 | LEFT JOIN |
| 内关联 | 关联字段!inner(子字段1,子字段2) | 使用 INNER JOIN,只返回两表都有数据的记录 | INNER JOIN |
关联字段表达方式
| 表达方式 | 语法 | 示例 | 说明 |
|---|---|---|---|
| 外键字段名 | 外键字段(子字段列表) | director_id(name,country) | 最常用方式,直接使用外键字段名 |
| 关联表名 | 表名(子字段列表) | director(name,country) | 使用被关联的表名 |
| 外键约束名 | 约束名(子字段列表) | fk_relate_director(name,country) | 使用外键约束的名称 |
别名设置
| 用法 | 语法 | 示例 | 说明 |
|---|---|---|---|
| 字段别名 | 别名:关联字段(子字段列表) | d:director_id(name,country) | 为关联字段设置别名 |
| 自关联别名 | 别名1:字段1(...),别名2:字段2(...) | manager:manager_id(name),mentor:mentor_id(name) | 自关联时必须使用别名区分 |
多对一
表和E-R
查询示例
需求:查询电影信息,同时获取对应导演的详细信息
说明:通过外键字段 director_id 关联 director 表,获取导演的 id、姓名和国籍信息。使用外关联方式,即使某些电影没有导演信息也会返回电影记录。
curl -i -X GET 'http://{{host}}/v1/rdb/rest/film?select=id,title,release_year,duration,director_id(id,name,country)' \
-H 'Authorization: Bearer <access_token>'
请求返回示例
HTTP/1.1 200 OK
Header:
content-length: 573
content-type: application/json; charset=utf-8
Body:
[
{
"director_id": {
"country": "USA",
"id": 1,
"name": "Steven Spielberg"
},
"duration": 164,
"id": 1,
"release_year": 1993,
"title": "Jurassic Park"
},
{
"director_id": {
"country": "UK",
"id": 2,
"name": "Christopher Nolan"
},
"duration": 172,
"id": 2,
"release_year": 2010,
"title": "Inception"
},
{
"director_id": {
"country": "Japan",
"id": 3,
"name": "Hayao Miyazaki"
},
"duration": 98,
"id": 3,
"release_year": 2001,
"title": "Spirited Away"
},
{
"director_id": null,
"duration": 100,
"id": 4,
"release_year": 2020,
"title": "Unknown Film 1"
},
{
"director_id": null,
"duration": 100,
"id": 5,
"release_year": 2015,
"title": "Untitled Project"
}
]
一对多
表和E-R
查询示例
需求:查询电影信息,同时获取该电影的所有评论
说明:通过反向关联查询,从 film 表查询关联的 review 表数据。系统会自动识别 review 表中的 film_id 外键,返回该电影的所有评论内容。
curl -i -X GET 'http://{{host}}/v1/rdb/rest/film?select=id,title,release_year,duration,review(content)' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <access_token>'
请求返回示例
HTTP/1.1 200 OK
Header:
content-length: 437
content-type: application/json; charset=utf-8
Body:
[
{
"duration": 142,
"id": 1,
"release_year": 1994,
"review": [
{
"content": "One of the greatest movies ever made!"
},
{
"content": "Tim Robbins and Morgan Freeman delivered outstanding performances."
}
],
"title": "The Shawshank Redemption"
},
{
"duration": 173,
"id": 2,
"release_year": 1972,
"review": [
{
"content": "Marlon Brando's performance is legendary."
}
],
"title": "The Godfather"
},
{
"duration": 98,
"id": 3,
"release_year": 1994,
"review": [
],
"title": "Pulp Fiction"
}
]
一对一
表和E-R
查询示例
需求:查询电影信息及其获奖情况
说明:一对一关系查询,每部电影最多对应一个奖项记录。
curl -i -X GET 'http://{{host}}/v1/rdb/rest/film?select=id,title,release_year,duration,award(award_name,year)' \
-H 'Authorization: Bearer <access_token>'
请求返回示例
HTTP/1.1 200 OK
Header:
content-length: 354
content-type: application/json; charset=utf-8
Body:
[
{
"award": {
"award_name": "Best Picture Nominee",
"year": 1994
},
"duration": 142,
"id": 1,
"release_year": 1994,
"title": "The Shawshank Redemption"
},
{
"award": null,
"duration": 154,
"id": 3,
"release_year": 1994,
"title": "Pulp Fiction"
}
]
多对多
表和E-R
关系识别规则
💡 注意:多对多关系需要通过中间表实现,中间表必须包含两个外键字段作为联合主键的一部分
系统会自动识别多对多关系,无需在请求中指定中间表。
查询示例
需求:查询电影信息及参演的演员列表
说明:通过中间表 film_actor 实现多对多关联,系统自动识别关系并返回每部电影的演员信息。
curl -i -X GET 'http://{{host}}/v1/rdb/rest/film?select=id,title,release_year,duration,actor(name,country)' \
-H 'Authorization: Bearer <access_token>'
请求返回示例
HTTP/1.1 200 OK
Header:
content-length: 367
content-type: application/json; charset=utf-8
Body:
[
{
"actor": [
{
"country": "USA",
"name": "Morgan Freeman"
}
],
"duration": 142,
"id": 1,
"release_year": 1994,
"title": "The Shawshank Redemption"
},
{
"actor": [
],
"duration": 175,
"id": 3,
"release_year": 1972,
"title": "The Godfather"
}
]
自关联
表和E-R
查询示例
需求:查询员工信息,同时获取其上级和导师信息
说明:自关联查询必须使用别名区分不同的关联字段。这里使用 manager 和 mentor 别名分别表示上级和导师关系。
curl -i -X GET 'http://{{host}}/v1/rdb/rest/employee?select=name,position,manager:manager_id(name,position),mentor:mentor_id(name,position)' \
-H 'Authorization: Bearer <access_token>'
请求返回示例
HTTP/1.1 200 OK
Header:
content-length: 979
content-type: application/json; charset=utf-8
Body:
[
{
"manager": null,
"mentor": null,
"name": "John Smith",
"position": "CEO"
},
{
"manager": null,
"mentor": null,
"name": "Sarah Johnson",
"position": "CTO"
}
]