Upload
andrey-gershun
View
140
Download
8
Embed Size (px)
Citation preview
1
Alasql.jsбаза данных SQL
на JavaScriptАндрей Гершун
[email protected]://github.com/agershun/alasql
MoscowJS29 января 2015 года
à laSQL
2
1. Что такое Alasql.js?2. Примеры использования Alasql3. Alasql изнутри4. Оптимизация
“Alasql - à la SQL parce que le monde entier envie notre belle langue”
Maxime Bertonnier, blogwebdev.fr
4
Alasql.js – SQL на JavaScript?… Хм.
• Сложные SQL запросы и быстрая обработка данных на клиенте:
• WHERE• GROUP BY• HAVING• ORDER BY• JOIN• APPLY
• CSV, TAB, XLS, JSON
5
Применение
• Фронт-энд для Business Intelligence приложений
• OLAP• таблицы
• Client First • мобильные приложения с
неустойчивой связью с сервером
6
Какие клиентские 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
7
Подключение 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’);
8
Использование Alasql
Синхронный интерфейс:var res = alasql(sql, params);
Асинхронный интерфейс:alasql(sql, params, function(res, err) {
// res – результаты, err - ошибка});
9
Пример выполнения SQL-операторовalasql('CREATE DATABASE TEST01; \
USE TEST01; \
CREATE TABLE jedi ( \
jediid INT, \
name STRING \
); \
INSERT INTO jedi VALUES \
(100, “Анакин Скайуокер")'
);
Перевод на JavaScriptvar jedi = [];
jedi.pop({studentid: 100, name:‘Анакин Скайуокер'});
10
Пример SQL-запроса
var num = alasql('SELECT VALUE COUNT(*) FROM jedi');
Перевод на JavaScript
var num = jedi.length;
11
Реализованная функциональность 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)
12
Реализованная функциональность SQL• ROLLUP, CUBE, GROUPING
SETS• INNER LEFT RIGHT OUTER
SEMI ANTI NATURAL CROSS JOIN
• CROSS OUTER APPLY• Вложенные SELECT, EXISTS,
ANY, SOME
13
SQL и JavaScript – лучше вместе!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});
14
Сколько строк нужно на 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() … - непросто…
16
Работа с объектами и функциями JavaScript var data = [
{a:{b:[1,2,3,4]}, {a:{b:[2014,2015]}}
];
alasql(‘SELECT a->b->length FROM ?’,[data]);
Результат: [4,2]
17
Загрузка данных из файлов в браузере,
Загрузка данныхс сервера
Загрузка данныхс десктопа
Экспорт данныхна десктоп
Источники данных:• JSON• CSV, TAB• XLS, XLSX • Google Spreadsheets• HTML (тэг <table>)
20
Alasql для d3.js:Олимпийские медали из Excelalasql('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 - выборка медали по заданной оси
});
25
Пример: Подготовка данных для Google Maps из Slideshare.com
Данныепо
просмотрам
XLSX(на сервере)
Гео данныепо странам
CSV(в Интернете)
Данныепо
просмотрампо странамс указанием
широтыи долготы
МассивJavaScript
slideshare.com
github.com
GoogleMaps APIJOIN
26
SELECT countries.*, views.cntFROM (
SELECT Country, COUNT(*) AS cntFROM "all_latest_views_3m.csv"GROUP BY Country
) AS viewsJOIN (
SELECT *FROM "https://abc.com/lat-long-countries.csv
") AS countries USING Country
27
Alasql из консоли: Простой ETL
> node alacon “SELECT 2+2”4
> node alacon “SELECT * INTO 'medals.csv' FROM 'medals.xlsx' WHERE Year=2008”
28
SQL2: Alasql вместе с IndexedDB (а также Local Storage, File Storage, SQL.js)
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
29
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();
30
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>
31
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>
32
Alasql изнутри
1. Лексер и парсер• Jison
2. Интерпретатор• Интерпретация «больших» операторов
(CREATE DATABASE, CREATE TABLE и др.)
3. Компилятор• Компиляция «критичных по скорости»
операторов SELECT/INSERT/UPDATE/DELETE
33
Оптимизация запросов
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
35
Оптимизация 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
36
Компиляция критических операций(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);
37
«Классическая» оптимизация JavaScript• for быстрее, чем forEach и т.д.•some быстрее, чем filter()•parseInt(x,10) быстрее, чем x|0
jsPerf.com - лучший советчик…