跳到主要内容

关联关系详解

什么是关联关系

关联关系是指数据模型之间的连接关系,通过关联字段将不同模型的数据关联起来。例如:

  • 学生属于某个班级(学生 → 班级)
  • 文章有多个评论(文章 → 评论)
  • 用户有一个个人资料(用户 → 个人资料)

关联关系类型

一对一(1:1)

一个记录只能关联另一个模型的一个记录。

示例:用户 ↔ 个人资料

// 用户模型
{
name: "张三",
profile: {
_id: "profile_123"
} // 关联个人资料
}

// 个人资料模型
{
_id: "profile_123",
avatar: "avatar.jpg",
bio: "个人简介"
}

一对多(1: N)

一个记录可以关联另一个模型的多个记录。

示例:班级 ↔ 学生

// 班级模型
{
name: "一年级1班",
students: [{
_id: "student_1"
},
{
_id: "student_2"
}
]
}

多对一(N:1)

多个记录关联另一个模型的一个记录。

示例:学生 ↔ 班级

// 学生模型
{
name: "小明",
class: {
_id: "class_123"
} // 多个学生属于同一个班级
}

多对多(M: N)

多个记录可以关联另一个模型的多个记录。

示例:学生 ↔ 课程

// 学生模型
{
name: "小明",
courses: [{
_id: "course_1"
}, // 语文
{
_id: "course_2"
} // 数学
]
}

支持的数据库类型

数据库类型支持的关联关系
云数据库(文档型)一对一、一对多、多对一
云数据库(MySQL)一对一、一对多、多对一、多对多
自有MySQL数据库一对一、一对多、多对一、多对多

增删改查

查询

查询结果包含关联数据

// 查询文章及其评论
const {
data
} = await models.post.get({
filter: {
where: {
_id: {
$eq: "post_123"
}
}
},
select: {
_id: true,
title: true,
content: true,
// 包含关联的评论数据
comments: {
_id: true,
content: true,
createdAt: true
}
}
});

根据关联条件过滤

// 查询有评论的文章
const {
data
} = await models.post.list({
filter: {
relateWhere: {
comments: {
where: {
content: {
$nempty: true
} // 评论内容不为空
}
}
}
},
select: {
_id: true,
title: true,
comments: {
content: true
}
}
});

创建

创建时建立关联

关联关系字段需要以 {_id:xxx} 格式传入,其中 xxx 为关联数据的 _id

// 创建学生并关联班级和课程
const {
data
} = await models.student.create({
data: {
name: "小明",
age: 8,
// 关联班级(多对一)
class: {
_id: "class_123"
},
// 关联多个课程(多对多)
courses: [{
_id: "course_1"
},
{
_id: "course_2"
}
]
}
});

更新

// 更新学生的班级
const {
data
} = await models.student.update({
filter: {
where: {
_id: {
$eq: "student_123"
}
}
},
data: {
class: {
_id: "new_class_456"
}
}
});

删除

配置关联关系时,可以设置不同的删除行为:

  • 删除关联模型数据:删除主记录时,同时删除关联的记录
  • 不删除关联模型数据:只删除主记录,保留关联记录
  • 禁止删除存在关联关系的数据:如果存在关联记录,则禁止删除主记录

最佳实践

  1. 合理设计关联关系:根据业务需求选择合适的关联类型
  2. 避免过深的嵌套查询:影响查询性能
  3. 使用精确的字段选择:只查询需要的关联字段
  4. 注意循环引用:避免模型之间的循环关联

通过关联关系,可以轻松实现复杂的数据查询和操作,让数据模型更贴近真实的业务场景。