You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

外键值以数组形式存储时如何单次查询获取关联用户及报表数据?

解决方案

方案1:优雅封装(两次简单查询,写法简洁性能优异)

该方案适配中小数据量场景,两次简单单表查询的开销远低于复杂的JSON关联JOIN,维护成本更低。

  1. 先给UserReport模型添加字段类型转换,自动将存储的JSON格式user_id转为PHP数组:
// app/Models/UserReport.php
protected $casts = [
    'user_id' => 'array',
];
  1. 封装关联用户获取访问器,统一调用入口:
// app/Models/UserReport.php
public function getUsersAttribute()
{
    return User::whereIn('id', $this->user_id)->get();
}

使用方式非常简洁:

$report = UserReport::find($id);
$users = $report->users; // 直接获取关联用户集合

方案2:单次SQL查询(满足单次查询的需求)

基于MySQL原生JSON函数实现关联JOIN,单次查询即可同时拿到报表数据和对应关联用户,需要数据库支持JSON函数(MySQL 5.7+/MariaDB 10.2+及以上版本均支持):

$reportWithUsers = UserReport::select(
        'user_report.*',
        \DB::raw('JSON_ARRAYAGG(JSON_OBJECT(
            "id", users.id,
            "name", users.name,
            "email", users.email
        )) as users')
    )
    ->leftJoin('users', \DB::raw('JSON_CONTAINS(user_report.user_id, CAST(users.id AS JSON))'), '=', \DB::raw('1'))
    ->where('user_report.id', $id)
    ->groupBy('user_report.id')
    ->first();

// 关联用户数据可直接转为数组使用
$users = json_decode($reportWithUsers->users, true);

优化建议

如果后续业务量持续增长,建议改为规范的多对多关联设计:新增中间表user_report_user存储report_id和user_id的映射关系,使用Laravel默认的belongsToMany关联,查询性能和可维护性都会大幅提升。


内容的提问来源于stack exchange,提问作者Amit Senjaliya

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 13:15:03