"alasql.js — база данных sql на javascript" — Андрей Гершун,...

39
Alasql.js база данных SQL на JavaScript Андрей Гершун [email protected] https://github.com/agershun/alasql MoscowJS 29 января 2015 года à la SQL 1

Upload: moscowjs

Post on 16-Jul-2015

601 views

Category:

Software


6 download

TRANSCRIPT

Page 1: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

Alasql.jsбаза данных SQL

на JavaScriptАндрей Гершун

[email protected]

https://github.com/agershun/alasql

MoscowJS

29 января 2015 года

à la

SQL

1

Page 2: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

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

Ты помнишь, каквсе начиналось…

lodash v3.0.0_.sortByAll(collection, props)

3

Page 4: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

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

Применение

• Фронт-энд для Business Intelligence приложений • OLAP

• таблицы

• Client First • мобильные приложения с

неустойчивой связью с сервером

5

Page 6: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

Какие клиентские 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

Подключение 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

Использование Alasql

Синхронный интерфейс:

var res = alasql(sql, params);

Асинхронный интерфейс:

alasql(sql, params, function(res, err) {

// res – результаты, err - ошибка

});

8

Page 9: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

Пример выполнения 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

Пример SQL-запроса

var num = alasql('SELECT VALUE COUNT(*) FROM jedi');

Перевод на JavaScript

var num = jedi.length;

10

Page 11: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

Реализованная функциональность 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

Реализованная функциональность 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

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

Сколько строк нужно на 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

Сахар…

alasql(‘SELECT LEN(_) FROM “mytext.txt”’);

Результат: длины строк в файле mytext.txt

15

Page 16: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

Работа с объектами и функциями 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

Загрузка данных из файлов в браузере,

Загрузка данныхс сервера

Загрузка данныхс десктопа

Экспорт данныхна десктоп

Источники данных:• JSON• CSV, TAB• XLS, XLSX• Google Spreadsheets• HTML (тэг <table>)

17

Page 18: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

18

Page 19: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

19

Page 20: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

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

21

Page 22: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

22

Page 23: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

23

Page 24: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

24

Page 25: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

Пример: Подготовка данных для Google Maps из Slideshare.com

Данныепо

просмотрам

XLSX(на сервере)

Гео данныепо странам

CSV(в Интернете)

Данныепо

просмотрампо странамс указанием

широтыи долготы

МассивJavaScript

slideshare.com

github.com

GoogleMaps APIJOIN

25

Page 26: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

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

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

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

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

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

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

Alasql изнутри

1. Лексер и парсер• Jison

2. Интерпретатор• Интерпретация «больших» операторов

(CREATE DATABASE, CREATE TABLE и др.)

3. Компилятор• Компиляция «критичных по скорости»

операторов SELECT/INSERT/UPDATE/DELETE

32

Page 33: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

Оптимизация запросов

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

34

http://jsperf.com/alasql-js-vs-websql/7

Page 35: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

Оптимизация 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

Компиляция критических операций(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

«Классическая» оптимизация JavaScript

• for быстрее, чем forEach и т.д.

•some быстрее, чем filter()

•parseInt(x,10) быстрее, чем x|0

jsPerf.com - лучший советчик…

37

Page 38: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

Тестирование

•Mocha.js

•240+ тестов для Node.js и браузера

•Нужно не менее 2000…

38

Page 39: "Alasql.js — база данных SQL на JavaScript" — Андрей Гершун, MoscowJS 18

[email protected]

@agershun

GitHub

• https://github.com/agershun/alasql

Что дальше?

39