我从第 3 方获得了一些记录(大约 30k),其结构与此类似(所有字符串):
first_name, last_name, city
另外我在 MySQL 中有 2 个表:用户和城市(大约 25k 条记录)。users 表有一个到城市表的外键。
我需要users用来自 api 的记录和citites表的外键来填充表。如果城市不存在,我需要创建它。所以我的代码是这样的:
<?php
$users = $api->getUsers();
$existingUsers = $this->userRepository->getIds();
$existingCities = $this->cityRepository->geIdsIndexedByName();
$db->beginTransaction();
foreach ($users as $i => $user) {
// if no city with such name, then create new and insert to array
if (!array_key_exists($user['city'], $existingCities) {
$cityId = $db->insert('cities', ['name' => $user['city']]);
$existingCities[$user['city_id']] = $cityId;
}
$user['city_id'] = $existingCities[$user['city']];
if (in_array($user['id'], $existingUsers) { // if record with such id exists, then we update it
$db->update('users', $user);
} else {
$db->insert('users', $user);
}
if (($i % 100) === 0) { // use transactions to avoid mass inserts and updates
$db->commit();
$db->beginTransaction();
}
}
我不喜欢的是,我必须将所有城市和所有用户加载到内存中以检查记录是否已经存在。我这里不使用 ORM,没有对象,只有很小的数组,但它仍然会占用资源,我想减少内存消耗。是否有任何实践可以优化该过程?
我有一个想法,将 NoSQL 存储用作现有用户和引用的缓存,但这是不允许的。
MM们