Как стать автором
Обновить

MySQL is NoSQL!

Время на прочтение2 мин
Количество просмотров4.3K
У MySQL, как известно, есть два недостатка*. Во-первых, язык запросов — SQL. Это исправляется с помощью HandlerSocket, о котором уже были статьи на хабре. Во-вторых, у него нет встроенного яваскрипта.

* — на самом деле, это шутка. недостатков у MySQL вряд ли именно два, но и заключаются они совершенно не в том, в чём я написал. а отсутствие яваскрипта — это, конечно, не недостаток. однако, если представить, что у MySQL нет SQL интерфейса вообще, то сравнивать его (как NoSQL-решение) нам придётся, в частности, с MongoDB, в котором интерпретатор яваскрипта есть.

Итак, я начал работы по второму направлению и уже получил кое-какой результат:


В настоящий момент можно делать следующее:
mysql> select execute_js("10+30") as r;
+----+
| r  |
+----+
| 40 |
+----+
1 row in set (0.08 sec)

Передали выражение, оно выполнилось и вернуло результат.

mysql> select execute_js("function f(x){return x+20;}; f(30)") as r;
+----+
| r  |
+----+
| 50 |
+----+
1 row in set (0.08 sec)

Аналогично: сделали функцию, вызвали её, вернули результат из функции.

mysql> select execute_js("function func(x){ return x*1+10;}", "func","20") as r; #описание см. ниже
+----+
| r  |
+----+
| 30 |
+----+
1 row in set (0.08 sec)

mysql> select execute_js("require('/tmp/func.js')", "func","30") as r; #описание см. ниже
+----+
| r  |
+----+
| 40 |
+----+
1 row in set (0.08 sec)


Тут мы (1) инициализируем чем-то глобальный объект, (2) указываем имя функции, которую нужно будет вызвать, (3 — ...) вызываем её с этими параметрами. Зачем это нужно?

mysql> select execute_js("require('/tmp/func.js');","func",CONCAT(num.i,"")) as r from num;
+----+
| r  |
+----+
| 11 |
| 12 |
| 13 |
| 13 |
| 15 |
| 16 |
| 16 |
| 16 |
| 19 |
| 19 |
| 19 |
| 20 |
+----+
12 rows in set (0.08 sec)

Вот зачем: мы один раз создаём глобальный объект, один раз создаём там функцию, но вызываем функцию уже несколько раз и с разными параметрами.
Как многие уже догадались, 0.08 секунды — это время инициализации V8. Естественно, можно и нужно инициализировать V8 не по одному разу на каждый запрос, а один раз для каждого потока, или как-то ещё более хитро.

посмотреть исходники

TODO LIST:
1. обработка ошибок / стабильность. сейчас при синтаксических ошибках всё падает.
2. пореже инициализировать интерпретатор V8
3. mysql_find — NoSQL-интерфейс к содержимому баз MySQL. тут я пока разбираюсь с locks и transactions. например, должны ли все операции выполняться в рамках одной транзакции, или одна операция — одна транзакция? или давать вообще интерфейс только для чтения?

Буду рад замечаниям и предложениям.
Теги:
Хабы:
Всего голосов 114: ↑83 и ↓31+52
Комментарии81

Публикации