Я довольно долго откладывал этот анонс, но теперь его время пришло.
Встретиться: узел-mysql-libmysqlclient v0.0.7 , MySQL-коннектор для Node.js, поддерживающий синхронное и асинхронное выполнение запросов к базе данных и имеющий API, близкий к API аналогичных коннекторов для PHP/Perl/Ruby и т. д.
MySQL и Node.js: история взаимоотношений
Node.JS разрабатывался в основном для написания быстрых асинхронных серверов (см.[1]), для обслуживания очередей сообщений, возврата небольших объемов статических данных и других задач, оперирующих с небольшими объемами данных.
Поэтому первыми появились коннекторы к базам данных NoSQL и Memcached. На том этапе разработки Node.JS казалось, что он охватывает большую часть возможных вариантов использования системы.
Если нужно было работать с реляционными базами данных, писался демон на другом языке, который готовил данные для Node.js-сервера.
Как вы понимаете, это замедлило развитие Node.js, поскольку многие привыкли поддерживать реляционные базы данных в стандартных библиотеках распространенных серверных языков программирования.
Этого не опроверг разработчик Node.js, который планировал включить подобные коннекторы в одну из более поздних стабильных версий.
Однако этого пока не произошло, и начали появляться сторонние коннекторы к реляционным базам данных.
На момент написания node-mysql-libmysqlclient их было несколько:
Еще один коннектор MySQL для Node.js?
На мой взгляд, у всех были свои недостатки.Конечно, удобно написать коннектор прямо на Javascript, как это было сделано в node-mysql. Однако это достаточно большой объем кода, который необходимо тщательно тестировать и скрупулезно обновлять при изменении API Node.js. Также, как оказалось, реализация на C/C++ происходит в 3-5 раз быстрее, чем на JavaScript. Чтобы использовать node.dbslayer.js, вы должны использовать слой в форме DBsLayer, чтобы обеспечить асинхронное выполнение запросов.
В первых реализациях Node_postgres имел очень мало функций.
И ни один из этих разъемов не приблизился к таковым на других языках по наличию утилитарных функций.
Это была основная причина, по которой я начал писать node-mysql-libmysqlclient.
Node-mysql-libmysqlclient: возможности
В настоящее время реализовано привязки для всех функций API библиотеки libmysqlclient, относящиеся к утилитарным функциям, выполнению запросов и получению данных.Коннектор также позволяет выполнять запросы асинхронно, с обратным вызовом или без него.
Пример:
/* http://gist.github.com/537870 */ var mysql_libmysqlclient = require("mysql-libmysqlclient"); var conn = mysql_libmysqlclient.createConnection(host, user, password, database); if (!conn.connected()) { sys.puts("Connection error: " + conn.connectErrno() + ", " + conn.connectError()); process.exit(1); } var string = conn.escape("Sannis's code"); /* Sync queries */ var res = conn.query("CREATE TEMPORARY TABLE t1 (alpha INTEGER, beta VARCHAR(255), pi FLOAT);"); sys.puts("'CREATE TABLE' result: " + sys.inspect(res)); res = conn.query("INSERT INTO t1 VALUES (1, 'hello', 3.141);"); sys.puts("LastInsertId: " + sys.inspect(conn.lastInsertId())); /* Async queries */ conn.queryAsync("INSERT INTO t1 VALUES (2, 'world', 2.718);", function (res) { conn.queryAsync("SELECT * FROM t1;", function (res) { sys.puts("NumRows: " + res.numRows()); var rows = res.fetchAll(); sys.puts("Rows: " + sys.inspect(rows)); conn.queryAsync("DELETE * FROM t1;"); }); });
Ближайшие планы
- Больше тестов, особенно для асинхронных запросов
- Обновить документацию по API и написать примеры использования для всех функций.
- Написание тестов для всех существующих на данный момент коннекторов к MySQL.
- Реализация подготовленных заявлений
Реализация асинхронности
Библиотека libmysqlclient изначально не поддерживает асинхронное выполнение запросов.Второй вызов mysql_query() до того, как будут получены все результаты из mysql_use_result() или вызов mysql_store_result(), приведет к ошибке.
Однако существует недокументированная функция mysql_send_query, которую использует разработчик коннектора mysql2 для Ruby, но я решил не идти по этому пути.
Для поддержки асинхронных операций ввода-вывода Node.js включает библиотеку Либейо .
Он не только поддерживает выполнение дисковых операций с обратными вызовами для получения результата, но и позволяет с помощью eio_custom выполнять любую функцию в отдельном потоке и возвращать результат ее выполнения в обратный вызов.
В libeio используется пул потоков, поэтому, чтобы избежать параллельного выполнения mysql_query, он дополнительно обертывается мьютексом.
Возможно, текущая реализация не выдержит конкуренции в случае высокой нагрузки на event-loop или libeio threads-pool, и тогда я думаю мы вернемся к системе с очередью запросов, когда очередь будет отвечать за последовательный запуск mysql_query и использование мьютекса не потребуется.
Фрагмент кода, отвечающий за асинхронные запросы: github.com/Sannis/node-mysql-libmysqlclient/blob/v0.0.7/src/mysql_bindings_connection.cc#L825-946
Ссылки по теме
[1] Веб-сайт Node.js [2] Node.js на GitHub [3] Node-mysql-libmysqlclient на GitHub [4] API узла-mysql-libmysqlclient P.S. У меня достаточно кармы, чтобы опубликовать тему в тематическом блоге.Но я никак не могу решить, какой из них будет для него лучше: JavaScript или Веб-разработка ? Теги: #node.js #node.js #MySQL #node-mysql-libmysqlclient #async #JavaScript #V8 #node.js
-
Ведение Блога Для Подростков
19 Oct, 24 -
Что Нового В Программировании На Python?
19 Oct, 24 -
Кельтские Языки
19 Oct, 24 -
Правила Высокой Производительности
19 Oct, 24 -
Первый В Истории Фестиваль Хакерства Reactos
19 Oct, 24