"alasql.js — база данных sql на javascript" — Андрей Гершун,...
TRANSCRIPT
![Page 1: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/1.jpg)
Alasql.jsбаза данных SQL
на JavaScriptАндрей Гершун
https://github.com/agershun/alasql
MoscowJS
29 января 2015 года
à la
SQL
1
![Page 2: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/2.jpg)
1. Что такое Alasql.js?
2. Примеры использования Alasql
3. Alasql изнутри
4. Оптимизация
“Alasql - à la SQL parce que le monde entier envie notre belle langue”
Maxime Bertonnier, blogwebdev.fr
2
![Page 3: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/3.jpg)
Ты помнишь, каквсе начиналось…
lodash v3.0.0_.sortByAll(collection, props)
3
![Page 4: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/4.jpg)
Alasql.js – SQL на JavaScript?… Хм.
• Сложные SQL запросы и быстрая обработка данных на клиенте:• WHERE
• GROUP BY
• HAVING
• ORDER BY
• JOIN
• APPLY
• CSV, TAB, XLS, JSON
4
![Page 5: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/5.jpg)
Применение
• Фронт-энд для Business Intelligence приложений • OLAP
• таблицы
• Client First • мобильные приложения с
неустойчивой связью с сервером
5
![Page 6: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/6.jpg)
Какие клиентские SQL базы данныхсуществуют для JavaScript?• «Полноценные» SQL
• WebSQL (SQLite) – «вне стандарта» с 2011 года • SQL.js (SQLite) – (1.5 Мб), Emscripten, небыстрый• SequelSphere.js – закрытый код
• LINQ• SQLike.js• JSLinq.js и др.
• NoSQL • IndexedDB• Key-value хранилища• PouchDB, ydn-db• CrossFilter.js
6
![Page 7: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/7.jpg)
Подключение Alasql.js
Браузер
<script src=“alasql.js></script>
<script>
alasql(‘CREATE DATABASE test01’);
</script>
AMD или UMD
require([‘alasql’], function(alasql) {
alasql(‘SELECT * FROM courses’);
});
Node.js
npm install alasql
var alasql = require(‘alasql’);
7
![Page 8: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/8.jpg)
Использование Alasql
Синхронный интерфейс:
var res = alasql(sql, params);
Асинхронный интерфейс:
alasql(sql, params, function(res, err) {
// res – результаты, err - ошибка
});
8
![Page 9: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/9.jpg)
Пример выполнения SQL-операторов
alasql('CREATE DATABASE TEST01; \
USE TEST01; \
CREATE TABLE jedi ( \
jediid INT, \
name STRING \
); \
INSERT INTO jedi VALUES \
(100, “Анакин Скайуокер")'
);
Перевод на JavaScript
var jedi = [];
jedi.pop({studentid: 100, name:‘Анакин Скайуокер'});
9
![Page 10: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/10.jpg)
Пример SQL-запроса
var num = alasql('SELECT VALUE COUNT(*) FROM jedi');
Перевод на JavaScript
var num = jedi.length;
10
![Page 11: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/11.jpg)
Реализованная функциональность SQL• WITH SELECT TOP INTO FROM GROUP BY HAVING WHERE LIMIT FETCH
• SUM, COUNT, DISTINCT, MIN, MAX, FIRST, LAST
• ROLLUP(), CUBE(), GROUPING SETS()
• INNER LEFT RIGHT OUTER SEMI ANTI NATURAL CROSS JOIN
• UNION ALL EXCEPT INTERSECT
• CROSS OUTER APPLY
• Вложенные SELECT, EXISTS, ANY, SOME
• INSERT DELETE UPDATE
• CREATE DROP ATTACH USE DATABASE, SHOW DATABASES
• CREATE DROP TABLE, PRIMARY KEY, CREATE DROP VIEW
• IF ELSE WHILE BEGIN END
• DECLARE SET
• BEGIN COMMIT ROLLBACK TRANSACTION (ограничено)
• Стандартные функции, CAST/CONVERT
• a la LINQ (fluent interface)11
![Page 12: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/12.jpg)
Реализованная функциональность SQL
•ROLLUP, CUBE, GROUPING SETS
• INNER LEFT RIGHT OUTER SEMI ANTI NATURAL CROSS JOIN
•CROSS OUTER APPLY
•Вложенные SELECT, EXISTS, ANY, SOME
12
![Page 13: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/13.jpg)
SQL и JavaScript – лучше вместе!
13
var data = [[1,2,3], [2,3,4], [5,6,7]
];var res = alasql('SELECT * FROM ? \
WHERE [0] < ?',[data, 2]);
Перевод на JavaScriptvar res = data.filter(function(d){return d[0] < 2});
![Page 14: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/14.jpg)
Сколько строк нужно на JavaScript,чтобы реализовать SQL запрос?SELECT COUNT(*) FROM students
LEFT JOIN courses USING courseid
LEFT JOIN schools ON students.schoolid = schools.schoolid
WHERE courseid > 3
GROUP BY schools.schoolid, courses.courseid
ORDER BY courseid DESC, schoolid
Инструменты JavaScript:• filter(), sort(), map(), reduce(), every(), some() … - непросто…
14
![Page 15: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/15.jpg)
Сахар…
alasql(‘SELECT LEN(_) FROM “mytext.txt”’);
Результат: длины строк в файле mytext.txt
15
![Page 16: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/16.jpg)
Работа с объектами и функциями JavaScript
var data = [
{a:{b:[1,2,3,4]},
{a:{b:[2014,2015]}}
];
alasql(‘SELECT a->b->length FROM ?’,[data]);
Результат: [4,2]
16
![Page 17: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/17.jpg)
Загрузка данных из файлов в браузере,
Загрузка данныхс сервера
Загрузка данныхс десктопа
Экспорт данныхна десктоп
Источники данных:• JSON• CSV, TAB• XLS, XLSX• Google Spreadsheets• HTML (тэг <table>)
17
![Page 18: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/18.jpg)
18
![Page 19: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/19.jpg)
19
![Page 20: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/20.jpg)
Alasql для d3.js:Олимпийские медали из Excel
20
alasql('SELECT '+axe+', \
SUM([Gold Medals]) AS Gold, \
SUM([Silver Medals]) AS Silver, \
SUM([Bronze Medals]) AS Bronze \
FROM "medals.csv" \
GROUP BY '+axe+'
ORDER BY '+axe,[],function (data){
// data - выборка медали по заданной оси
});
![Page 21: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/21.jpg)
21
![Page 22: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/22.jpg)
22
![Page 23: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/23.jpg)
23
![Page 24: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/24.jpg)
24
![Page 25: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/25.jpg)
Пример: Подготовка данных для Google Maps из Slideshare.com
Данныепо
просмотрам
XLSX(на сервере)
Гео данныепо странам
CSV(в Интернете)
Данныепо
просмотрампо странамс указанием
широтыи долготы
МассивJavaScript
slideshare.com
github.com
GoogleMaps APIJOIN
25
![Page 26: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/26.jpg)
SELECT countries.*, views.cnt
FROM (
SELECT Country, COUNT(*) AS cnt
FROM "all_latest_views_3m.csv"
GROUP BY Country
) AS views
JOIN (
SELECT *
FROM "https://abc.com/lat-long-countries.csv"
) AS countries USING Country
26
![Page 27: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/27.jpg)
Alasql из консоли: Простой ETL
> node alacon “SELECT 2+2”
4
> node alacon “SELECT * INTO 'medals.csv'
FROM 'medals.xlsx' WHERE Year=2008”
27
![Page 28: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/28.jpg)
SQL2: Alasql вместе с IndexedDB(а также Local Storage, File Storage, SQL.js)
28
CREATE INDEXEDDB DATABASE IF NOT EXISTS geo;
ATTACH INDEXEDDB DATABASE geo;
USE geo;
DROP TABLE IF EXISTS cities;
CREATE TABLE cities;
SELECT * INTO cities FROM ?;
SELECT COLUMN * FROM cities WHERE population > 100000 ORDER BY city DESC
![Page 29: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/29.jpg)
A la LINQ. Текучий интерфейс ;)var data = [{a:1,b:1},{a:2,b:-1},
{a:3,b:3},{a:1,b:5}];
var res = alasql(data).Top(2).GroupBy("a").exec();
29
![Page 30: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/30.jpg)
Alasql в обычном режиме<script src="alasql.min.js"></script>
<script>
var arr = [{a:1},{a:2},{a:1}];
alasql('CREATE TABLE one (a INT); \
INSERT INTO one VALUES(10); \
SELECT * INTO one FROM ?; \
SELECT * FROM one',[arr], function(data){
// Выполняется в основном потоке
});
</script>30
![Page 31: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/31.jpg)
Alasql в Worker<script src="alasql-worker.min.js"></script>
<script>
var arr = [{a:1},{a:2},{a:1}];
alasql('CREATE TABLE one (a INT); \
INSERT INTO one VALUES(10); \
SELECT * INTO one FROM ?; \
SELECT * FROM one',[arr], function(data){
// Выполняется в основном потоке
});
</script>31
![Page 32: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/32.jpg)
Alasql изнутри
1. Лексер и парсер• Jison
2. Интерпретатор• Интерпретация «больших» операторов
(CREATE DATABASE, CREATE TABLE и др.)
3. Компилятор• Компиляция «критичных по скорости»
операторов SELECT/INSERT/UPDATE/DELETE
32
![Page 33: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/33.jpg)
Оптимизация запросов
SELECT SUM(test1.one), test1.two, test2.three FROM test1 JOIN test2 ON test1.two = test2.two WHERE test1.one > 5 GROUP BY test1.two, test2.three ORDER BY three, sumone
33
![Page 34: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/34.jpg)
34
http://jsperf.com/alasql-js-vs-websql/7
![Page 35: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/35.jpg)
Оптимизация SQL• Анализ JOIN и WHERE выражений и преиндексация
FROM oneJOIN two USING eJOIN three ON two.a = three.a+1 AND two.b = three.c+three.dWHERE two.a > 10 AND three.c > 20
• Как сократить пробег?• one.length x two.length x three.length
• Оптимизиация• two.e - индекс (хэш) для demo.e• (three.a+1) +’#’+ (three.c+three.d) – индекс для (two.a) +’#’+ (two.b)• two.a > 10 – префильтрация массива one• three.c > 20 – префильтрация массива two
35
![Page 36: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/36.jpg)
Компиляция критических операций(SELECT, WHERE, ORDER BY, GROUP BY, HAVING, INSERT, DELETE, UPDATE):
SELECT * FROM data ORDER BY alpha, beta
var orderfns = “if(a.alpha>b.alpha) {return 1; else if(a.alpha==b.alpha) return 0;
if(a.beta>b.beta) {return 1; else if(a.beta==b.beta) return 0;}}return -1;”;
var orderfn = new Function(‘a,b’, orderfns);
var data = data.sort(orderfn);
36
![Page 37: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/37.jpg)
«Классическая» оптимизация JavaScript
• for быстрее, чем forEach и т.д.
•some быстрее, чем filter()
•parseInt(x,10) быстрее, чем x|0
jsPerf.com - лучший советчик…
37
![Page 38: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/38.jpg)
Тестирование
•Mocha.js
•240+ тестов для Node.js и браузера
•Нужно не менее 2000…
38
![Page 39: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18](https://reader036.vdocuments.mx/reader036/viewer/2022082216/55a77bc41a28abba668b45cc/html5/thumbnails/39.jpg)
@agershun
GitHub
• https://github.com/agershun/alasql
Что дальше?
39