关联关系详解
什么是关联关系
关联关系是指数据模型之间的连接关系,通过关联字段将不同模型的数据关联起来,实现数据之间的逻辑连接。
新建关联关系时,系统会在两个数据模型中分别建立关联字段,用于存储关联数据的 _id。
⚠️ 注意: MySQL数据模型中的关联关系字段是通过中间表进行关联的,因此不能直接通过SQL的JOIN语句进行查询。需要使用数据模型提供的关联查询方法来获取关联数据。
常见的关联关系场景:
- 学生属于某个班级(学生 → 班级)
- 学生模型关联字段:所属班级
 - 班级模型关联字段:学生列表
 
 - 文章有多个评论(文章 → 评论)
- 文章模型关联字段:评论列表
 - 评论模型关联字段:所属文章
 
 - 用户有一个个人资料(用户 → 个人资料)
- 用户模型关联字段:个人资料
 - 个人资料模型关联字段:所属用户
 
 
关联关系类型
一对一(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数据库 | 一对一、一对多、多对一、多对多 | 
关联关系操作
查询操作
💡 注意: 对于MySQL数据库,关联查询必须使用数据模型提供的查询方法,不支持直接使用SQL JOIN语句。
查询结果包含关联数据
// 查询文章及其评论
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" }
        ]
    }
});
更新操作
💡 注意:更新关联关系字段时,需要以
{_id: xxx}格式传入,其中xxx为关联数据的_id,无需传入其他字段。
// 更新学生的班级
const { data } = await models.student.update({
    filter: {
        where: {
            _id: { $eq: "student_123" }
        }
    },
    data: {
        class: {
            _id: "new_class_456"
        }
    }
});
删除操作
配置关联关系时,可以设置不同的删除行为:
- 删除关联模型数据:删除主记录时,同时删除关联的记录
 - 不删除关联模型数据:仅删除主记录,保留关联记录
 - 禁止删除存在关联关系的数据:如果存在关联记录,则禁止删除主记录
 

最佳实践
设计原则
- 合理选择关联类型:根据实际业务需求选择合适的关联关系类型
 - 避免过深嵌套:深层嵌套查询会影响性能,建议控制在 3 层以内
 - 精确字段选择:仅查询必要的关联字段,减少数据传输量
 - 避免循环引用:防止模型之间形成循环关联,导致查询死循环
 
性能优化
- 合理使用索引:为关联字段建立索引,提升查询效率
 - 分页查询:对于大量关联数据,使用分页避免一次性加载过多数据
 - 缓存策略:对于频繁查询的关联数据,考虑使用缓存机制
 
通过合理使用关联关系,可以构建灵活高效的数据模型,满足复杂业务场景需求。