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

Laravel 9中批量插入父子关联数据时将UUID替换为ID的实现方案

Laravel 9中批量插入父子关联数据时将UUID替换为ID的实现方案

嘿,我来帮你搞定这个批量插入关联数据时替换UUID为ID的问题!先看看你的表结构:

表结构

movies 表

iduuidtitle...
1uuid-m01movie 1...

categories 表

iduuidtitle...
1uuid-c01动作片...

接下来我分场景给你讲具体实现方式,都是实战里常用的套路:

一对多关联场景(比如分类下的电影)

假设我们要批量插入分类,同时插入属于这些分类的电影,电影数据里用分类的UUID来关联,插入后要把电影的category_id替换成分类的实际自增ID。

步骤1:批量插入父表数据,建立UUID与ID的映射

首先插入分类数据,然后通过UUID查询出对应的ID,存成一个映射数组,方便后续替换:

// 准备要插入的分类数据,每条都带唯一UUID
$categoryData = [
    ['uuid' => 'uuid-c01', 'title' => '动作片', 'created_at' => now(), 'updated_at' => now()],
    ['uuid' => 'uuid-c02', 'title' => '喜剧片', 'created_at' => now(), 'updated_at' => now()],
];

// 批量插入分类
\App\Models\Category::insert($categoryData);

// 生成UUID到ID的映射数组
$categoryUuidMap = \App\Models\Category::whereIn('uuid', collect($categoryData)->pluck('uuid'))
    ->pluck('id', 'uuid')
    ->toArray();

步骤2:处理子表数据,替换UUID为ID

接着把原始的电影数据里的分类UUID替换成对应的ID,再批量插入:

// 原始电影数据,用分类UUID关联
$movieData = [
    ['uuid' => 'uuid-m01', 'title' => '头号玩家', 'category_uuid' => 'uuid-c01', 'created_at' => now(), 'updated_at' => now()],
    ['uuid' => 'uuid-m02', 'title' => '夏洛特烦恼', 'category_uuid' => 'uuid-c02', 'created_at' => now(), 'updated_at' => now()],
];

// 转换数据:把category_uuid替换成category_id
$processedMovieData = collect($movieData)->map(function ($movie) use ($categoryUuidMap) {
    return [
        'uuid' => $movie['uuid'],
        'title' => $movie['title'],
        'category_id' => $categoryUuidMap[$movie['category_uuid']],
        'created_at' => $movie['created_at'],
        'updated_at' => $movie['updated_at'],
    ];
})->toArray();

// 批量插入电影
\App\Models\Movie::insert($processedMovieData);

步骤3:加上事务保证数据一致性

为了避免插入过程中出现错误导致数据不一致,最好把所有操作放在事务里:

\DB::beginTransaction();

try {
    // 插入分类并生成映射
    \App\Models\Category::insert($categoryData);
    $categoryUuidMap = \App\Models\Category::whereIn('uuid', collect($categoryData)->pluck('uuid'))
        ->pluck('id', 'uuid')
        ->toArray();

    // 处理并插入电影
    $processedMovieData = collect($movieData)->map(function ($movie) use ($categoryUuidMap) {
        return [
            'uuid' => $movie['uuid'],
            'title' => $movie['title'],
            'category_id' => $categoryUuidMap[$movie['category_uuid']],
            'created_at' => $movie['created_at'],
            'updated_at' => $movie['updated_at'],
        ];
    })->toArray();
    \App\Models\Movie::insert($processedMovieData);

    \DB::commit();
} catch (\Exception $e) {
    \DB::rollBack();
    // 这里可以根据需求处理错误,比如返回错误提示
    throw $e;
}

多对多关联场景(比如电影属于多个分类)

如果是多对多关系(有中间表movie_category),思路差不多,只是需要同时处理两个表的UUID映射:

  1. 先插入分类和电影,分别生成UUID到ID的映射
  2. 处理中间表数据,把电影UUID和分类UUID都替换成对应的ID
  3. 批量插入中间表数据

核心逻辑和一对多一致,只是多了一层映射处理,这里就不贴重复代码啦。

几个注意点

  • 确保你的uuid字段在表中是唯一索引,这样查询映射时不会出现重复ID的问题
  • 如果插入的数据量特别大,whereIn里的UUID数量别超过数据库限制,可以分成多批处理
  • 如果你用的是Laravel的insertGetId,它只会返回第一条插入记录的ID,所以用insert后再查询映射是更可靠的方式

备注:内容来源于stack exchange,提问作者Mr.Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 16:24:40