Я хочу обработать большое количество записей (> 400 000) в пакете и вставить их в базу данных.
Я знаю, как перебирать массив с помощью for() или underscore.each(), а также знаю, как асинхронно вставлять запись в различные базы данных SQL (без SQL). Проблема не в этом, проблема в том, что я не могу найти способ сделать и то, и другое одновременно.
Само распределение базы данных здесь роли не играет, принцип применим для любой базы данных (NO)SQL с асинхронным интерфейсом.
Я ищу шаблон для решения следующей проблемы:
Циклический подход:
var results = []; //imagine 100k objects here
_.each(results,function(row){
var newObj = prepareMyData(row);
db.InsertQuery(newObj,function(err,response) {
if(!err) console.log('YAY, inserted successfully');
});
});
Такой подход явно ошибочен. Это как бы забивает базу данных запросами на вставку, не дожидаясь завершения ни одного из них. Говоря об адаптерах MySQL, использующих пул соединений, вы довольно скоро исчерпаете соединения, и скрипт выйдет из строя.
Рекурсивный подход:
var results = []; //again, full of BIGDATA ;)
var index = 0;
var myRecursion = function()
{
var row = results[index];
var data = prepareMyData(row);
db.InsertQuery(data,function(err, response)
{
if (!err)
{
console.log('YAY, inserted successfully!');
index++; //increment for the next recursive call of:
if (index < results.length) myRecursion();
}
}
}
myRecursion();
В то время как этот подход работает довольно хорошо для небольших фрагментов данных (хотя он может быть медленным, но это нормально. цикл событий может некоторое время отдыхать, ожидая завершения запроса), он не работает для больших массивов - слишком много рекурсий .
Я мог бы легко написать пакетную вставку на любом другом процедурном языке, таком как PHP или около того, но я не хочу. Я хочу решить это асинхронно в nodejs - в образовательных целях.
Какие-либо предложения?