Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Отправка запросов в БД (https://javascript.ru/forum/misc/71698-otpravka-zaprosov-v-bd.html)

jtag 06.12.2017 10:34

Отправка запросов в БД
 
Всем добрый день. Сейчас отправляю запросы в mysql таким образом:
let x = 0;
setInterval(function(){
    connection.query("SELECT * FROM person WHERE x = '"+x+"' ... ", function() {
         x++;
    });
},500);


Из этого видно что setInterval абсолютно не видит когда приходит обратный ответ с БД. Время пол секунды, установлено приблизительно, т.к. я уверен чтоб БД уже завершила ответ. Как сделать чтобы после ответа сразу отправлялся след запрос? Существует какой-либо шаблон, по которому все пишут, а я вот его не знаю?

Nexus 06.12.2017 10:52

Зачем так бд сношать?

jtag 06.12.2017 11:00

события в бд поступают в реальном времени, строка за строкой. и нужно обрабатывать эти строки понемногу, вот и пытаюсь придумать цикл для обработки.

Nexus 06.12.2017 11:07

jtag, что значит "события поступают в бд"?

jtag 06.12.2017 11:11

события т.е. новые строки

laimas 06.12.2017 11:14

Цитата:

Сообщение от jtag
т.к. я уверен чтоб БД уже завершила ответ

Ну выборка из БД не ради шутки же, а нужны ее данные, а ответил ли sql-сервер и если да, то чем узнают не по уверенности, а проверкой ответа.

Nexus 06.12.2017 11:14

jtag, что мешает уже обработанным строкам добавлять флаг (либо хранить где-нибудь последний обработанный id) и запрашивать у бд сразу некоторое кол-во записей, которые нужно обработать?
Зачем каждые пол секунды долбить бд новым запросом?
Быстрее она от этого работать не станет.

jtag 06.12.2017 13:04

Незнаю можно ли тут обсуждать БД, но вот что у меня получается. Вначала я делаю выборку одним разом всех не обработанных строк. Потом в цикле начинаю обрабатывать каждую строку, т.е. делаю запрос в БД, существует ли такой ИИН, если нет такого, то вставляю в базу. Потом вставляю телефон, и делаю запрос - отмечаю необработанную строку флагом "обрабатано". Получается, мне нужно все используемые таблицы скопировать и потом с ними в обычном цикле for производить операции?
let x = 0;
con.query("SELECT * FROM xml_person WHERE done='0'", function (err, resultFromXml) { //запрос всех необработанных строк
		setInterval(function () {
			con.query("SELECT * FROM person  WHERE iin='" + resultFromXml[x].iin + "'", function (err, resultFromPerson) { //проверка, имеется ли такой ИИН в базе
				if (resultFromPerson.length == 0) {  
					con.query("INSERT INTO `person` (`idperson`, `iin`, `surname`, `name`,..., function(err) {		//вставка person

						con.query("INSERT INTO `phone` (`id`, `phone`," ... function(err) {		//вставка телефона
							con.query("UPDATE xml_person SET done='4' WHERE id_xml_person='" + resultFromXml[x].id_xml_person, function(err) {  //ставлю флаг, что строка обработана
								x++;
							}
						}
					});
				}
					
			});
		}, 500);
		
}

laimas 06.12.2017 13:21

jtag,
я не знаю node.js, но как можно обрабатывать результат запроса не зная, что он вернул? А если запрос завершился неудачей?

jtag 06.12.2017 13:29

я просто сократил и вырезал, а так там конечно, ошибки обрабатываются.

Nexus 06.12.2017 13:31

jtag, что мешает реализовать такой алгоритм:
Получаю список данных на обработку;
Собираю все айдишники пользователей в массив;
Запрашиваю из бд поля id и ИНН пользователей, чей id лежит в собранном массиве;
Создаю объект "insert", в который буду складывать данные для вставки в бд;
В цикле гоняю полученные данные заполняя объект "insert";
Если "insert" не пустой, создаю в бд сразу несколько записей на основе данных из этого объекта.

Описанный мною алгоритм требует всего 3 запроса и 1 цикл.

laimas 06.12.2017 13:33

Nexus,
по уму, так тут никаких циклов и требуется, собственно как и четыре запроса.

Nexus 06.12.2017 13:48

laimas, "insert select"?

jtag 06.12.2017 13:53

Спасибо. Попробую реализовать.

NeoN 06.12.2017 13:54

Цитата:

Сообщение от jtag (Сообщение 472199)
Всем добрый день. Сейчас отправляю запросы в mysql таким образом:
let x = 0;
setInterval(function(){
    connection.query("SELECT * FROM person WHERE x = '"+x+"' ... ", function() {
         x++;
    });
},500);


Из этого видно что setInterval абсолютно не видит когда приходит обратный ответ с БД. Время пол секунды, установлено приблизительно, т.к. я уверен чтоб БД уже завершила ответ. Как сделать чтобы после ответа сразу отправлялся след запрос? Существует какой-либо шаблон, по которому все пишут, а я вот его не знаю?

let x = 0;
function query(){
    connection.query("SELECT * FROM person WHERE x = '"+x+"' ... ", function() {
         x++;
		 setTimeout(query,500);
    });
}
query();

Nexus 06.12.2017 13:54

jtag, если у вас все необходимые данные есть в бд, то можно обойтись 1 запросом к бд.
Без циклов и прочего.

laimas 06.12.2017 14:07

Цитата:

Сообщение от Nexus
"insert select"?

Судя по запросам и описанию, это должен быть запрос UPDATE ... WHERE field IN(SELECT ... WHERE (SELECT ... WHERE ... NOT EXISTS))

Я не знаю node и для меня в запросах setTimeout(), это вообще какая-то дикость. :) Но то что запросы организованы не как полагается, это видно сразу.

Nexus 06.12.2017 14:14

laimas, я тоже ноду не знаю, но автору, вроде как нужно добавить пользователей, для которых в бд нет инн.

Nexus 06.12.2017 14:15

NeoN, я node.js не знаю, но не оцените ли саму идею этого кода? :)
class SomeClass{
	/**
	* @return Promise
	*/
	public getFirstOneBillionUsers(){
		return new Promise(function(resolve){
			var counter=0,
				users=[],
				request=function(){
					connection.query('SELECT * FROM users WHERE id>'+$counter+' LIMIT 1',function(user){
						counter++;
						users.push(user);
						
						if(counter<Math.pow(10,9))
							setTimeout(request,500);
						else
							resolve(users);
					});
				};
		});
	}
}
По-моему гениальный способ зад-чить бд :)
Примерное время выполнения метода: чуть меньше 16 лет.

Lion777 06.12.2017 14:33

процедуру напиши

laimas 06.12.2017 14:41

Цитата:

Сообщение от Nexus (Сообщение 472235)
laimas, я тоже ноду не знаю, но автору, вроде как нужно добавить пользователей, для которых в бд нет инн.

Ну так смотрите как при этом насилуется база. ) То что я написал, это логика, а чтобы точно написать, это нужно знать структуру таблиц и что требуется. Но из того что имеется, это - получить из таблицы А ID пользователей которых нет в таблице В и сделать многостраничную вставку этих пользователей в таблицу С.

Собрать перед запросом нечто чем потом оперировать дабы исключить циклы, это желательно, но что это, откуда взялось не знаю, а посему сказать трудно.


Часовой пояс GMT +3, время: 20:21.