mysql - 在 Laravel 5.4 中复制一条记录及其后代

标签 mysql laravel eloquent laravel-5.4 laravel-query-builder

我有当前的结构化数据库和 Eloquent 模型。

文档

编号

页面

id, document_id

Assets

id, page_id

所以我的文档有很多页面,有很多 Assets 。

我的文档模型中有一个非常丑陋的方法,该方法一直运行到现在,遍历所有页面然后 Assets 并复制它们,将新外键存储在新记录中。

    foreach ($pages as $page) {
        $replicatedPage = $page->replicate();
        $replicatedPage->document_id = $newDocument->id;
        $replicatedPage->save();

        foreach ($page->assets as $asset) {
            $replicatedAsset = $asset->replicate();
            $replicatedAsset->page_id = $replicatedPage->id;
            $replicatedAsset->save();
        }
    }

不幸的是,现在这变得非常慢,因为人们上传了近 200 个页面,每页 200 个 Assets (总共 40,000 个 Assets )。

我也研究了 saveMany() 函数,但在幕后,它只是通过迭代所述 ID 来完成我在上面所做的事情。

我真正需要的是一个很好的查询构建器来在 SQL 级别复制所有这些,但我不知道如何做到这一点。甚至我可以将原始 SQL 语句嵌入到原始查询构建器函数中。

有什么想法吗?

最佳答案

使用insert() 方法使其更快。急切加载文档及其所有页面和 Assets ,迭代此数据并为每个表构建一个数组。 pages 表的示例(对 assets 表执行相同操作):

$replicatedPages = [];
foreach ($pages as $page) {
    $replicatedPages[] = $page->toArray(); // Probably you'll need to remove ID column.
}
Page::insert($replicatedPages);

使用这种方法,您将只执行两次查询来插入所有文档的页面和 Assets ,而不是执行 40000 次查询。

关于mysql - 在 Laravel 5.4 中复制一条记录及其后代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45106817/

相关文章:

php - 在 Laravel 中添加 Sitemap 文件和路由

laravel - 在 Laravel 查询范围内查询相关模型

java - 由于底层异常 : com. mysql.cj.exceptions.WrongArgumentException,无法加载连接类

mysql - 同时连接到 mysql 数据库

java - 在 JDBC 连接字符串中选择负载平衡策略

javascript - Angularjs 'Access-Control-Allow-Origin' 多个子域请求

MYSQL:表之间的差异

php - laravel全文搜索多个关键字在一起

php - Laravel 更新方法不存在

php - 在 Laravel 5.8 中将关联数组传递给 where 子句