php laravel更新或创建海量数据

1zmg4dgp  于 2023-01-16  发布在  PHP
关注(0)|答案(1)|浏览(135)

我有一个案例,我需要每隔几分钟就将一个外部现有表与网站表同步。
我以前用一个简单的foreach来循环遍历每条记录,随着表的增长,它变得越来越慢,现在大约20.000条记录需要很长时间。
我想确保它创建一个新的记录或更新一个现有的。这是我得到的,但它似乎没有更新现有的行。

$no_of_data = RemoteUser::count(); // 20.000 (example)

        $webUserData = array();
        for ($i = 0; $i < $no_of_data; $i++) {
            // I check the external user so i can match it.
            $externalUser = RemoteUser::where('UserID', $i)
                ->first();

            if($externalUser) {
                $webUserData[$i]['username'] = $externalUser->username;
                $webUserData[$i]['user_id'] = $externalUser->UserID;
            }
        }

        $chunk_data = array_chunk($webUserData, 1000);
        if (isset($chunk_data) && !empty($chunk_data)) {
            foreach ($chunk_data as $chunk_data_val) {

                \DB::table('WebUser')->updateOrInsert($chunk_data_val);
            }
        }

我是否遗漏了什么,或者这是错误的方法?
先谢了

6yt4nkrj

6yt4nkrj1#

在我看来,这将是一个理想的场景,使用触发器,而不是外部的方法。
如果您复制的数据不需要外部解释器的干预,并且数据保留在数据库的进程中(这意味着源知道数据,因为它是从同一个源提取的),则可以使用SQL或数据库支持的任何SQL扩展。
我没有您的表的模式,所以我只使用我可以从您的问题中提取的信息,将其缩小到简单的user_idusername
我们需要改变这种情况,不再询问每个条目是否发生了更新或该行是否是新条目,而是让条目本身通知我们更新或插入。
我假设您使用的是MySQL,如果不是,SQL触发器在所有已知的支持SQL的数据库中都非常相似。
触发器结构具有如下简单布局:

CREATE TRIGGER trigger_name
AFTER UPDATE ON table_name 
FOR EACH ROW
  body_to_execute

其中AFTER_UPDATE是本例中要捕获的事件。
因此,对于更新事件,我们希望知道已更改的数据AFTER,它已被更新,因此我们将使用AFTER UPDATE触发器。
因此,表的AFTER UPDATEremote_user称为原始表,将web_user称为副本表,将user_idusername用作字段,如下所示

CREATE TRIGGER user_updated 
AFTER UPDATE ON remote_user 
FOR EACH ROW
  UPDATE web_user
     SET username = NEW.username
   WHERE user_id = NEW.user_id;

变量NEWOLD在触发器中可用,其中NEW拥有更新后的数据,OLD拥有更新前的数据。
对于已经插入的新用户,我们有相同的过程,我们只需要在web_user中创建条目。

CREATE TRIGGER user_created
AFTER INSERT on remote_user
FOR EACH ROW
  INSERT INTO web_user(user_id, username)
  VALUES(NEW.user_id, NEW.username);

希望这能让你对如何使用SQL触发器有一个清晰的概念。有很多信息可以找到,指南,教程,你能想到的。SQL可能是一种由长胡子的老人创造的古老无聊的语言,但是了解它的特性会给你一个很大的优势,用简单的方法解决复杂的问题。

相关问题