Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PouchDB или Что делать, когда “интернет стабильный” Зураб Белый, Рексофт, CEE-SECR 2017

F74d4292cc3b7b79920fcca339e02a21?s=47 CEE-SECR
October 21, 2017

PouchDB или Что делать, когда “интернет стабильный” Зураб Белый, Рексофт, CEE-SECR 2017

В докладе я расскажу про базу данных PouchDB, написанную на JavaScript, и постараюсь сделать общий обзор ее функциональности. Расскажу в каких условиях она будет работать, для каких целей ее можно использовать и какие проблемы решать. Покажу примеры работы с базовыми возможностями. Выступление ознакомительное и рассчитано на слушателей, не знакомых с этим продуктом.

F74d4292cc3b7b79920fcca339e02a21?s=128

CEE-SECR

October 21, 2017
Tweet

More Decks by CEE-SECR

Other Decks in Technology

Transcript

  1. Зураб Белый Рексофт 2017 или Что делать, когда “интернет стабильный”

  2. Не верьте мне Проверяйте всё сами Дисклеймер

  3. Знакомство с PouchDB

  4. Что это?

  5. Что это? NoSQL база данных в браузере

  6. Что это? NoSQL база данных в браузере Автоматическая синхронизация

  7. Что это? NoSQL база данных в браузере Автоматическая синхронизация Использует

    IndexedDB и WebSQL
  8. Что это? NoSQL база данных в браузере Автоматическая синхронизация Использует

    IndexedDB и WebSQL Free open-source
  9. Что это? NoSQL база данных в браузере Автоматическая синхронизация Использует

    IndexedDB и WebSQL Free open-source Интеграция с CouchDB
  10. Где работает?

  11. Где работает? Firefox 29+ (Including Firefox OS and Firefox for

    Android) Chrome 30+ Safari 5+ Internet Explorer 10+ Opera 21+ Android 4.0+ iOS 7.1+ Windows Phone 8+
  12. Где работает? Firefox 29+ Chrome 30+ Safari 5+ Internet Explorer

    10+ Opera 21+ Android 4.0+ iOS 7.1+ Windows Phone 8+
  13. Как работает?

  14. Как работает? PouchDB

  15. Как работает? PouchDB IndexedDB WebSQL LevelDB HTTP

  16. Как работает? PouchDB IndexedDB WebSQL HTTP LevelDB WebSQL SQLite Plugin

    node-websql CouchDB Cloudant PouchDB Server Couchbase SG LevelDOWN MemDOWN LocalStorageDOWN FruitDOWN
  17. Кто использует?

  18. Кто использует?

  19. Базовый API

  20. Создание базы данных

  21. Создание базы данных 1. const db = new PouchDB('databaseName');

  22. Создание базы данных 1. const db = new PouchDB('databaseName'); SQL

    concept PouchDB concept table no equivalent row document column field primary key primary key (_id) index view
  23. Синхронизация с серверной базой данных

  24. Синхронизация с серверной базой данных 1. const localDB = new

    PouchDB('databaseName');
  25. Синхронизация с серверной базой данных 1. const localDB = new

    PouchDB('databaseName'); 2. const remoteDbUrl = 'http://domain:5984/dbName';
  26. Синхронизация с серверной базой данных 1. const localDB = new

    PouchDB('databaseName'); 2. const remoteDbUrl = 'http://domain:5984/dbName'; 3. localDB.sync(remoteDbUrl, {live: true, retry: true});
  27. Работа с документами

  28. Работа с документами 1. db.get(data) 2. .then(doc => { /*

    do something with document */ }) 3. .catch(err => { /* errors handling */ });
  29. Работа с документами 1. db.get(data) 2. .then(doc => { /*

    do something with document */ }) 3. .catch(err => { /* errors handling */ }); 4. db.put(data) 5. .then(response => { /* handling result */ }) 6. .catch(err => { /* errors handling */ });
  30. Работа с документами 1. db.get(data) 2. .then(doc => { /*

    do something with document */ }) 3. .catch(err => { /* errors handling */ }); 4. db.put(data) 5. .then(response => { /* handling result */ }) 6. .catch(err => { /* errors handling */ }); 7. db.remove(data) 8. .then(response => { /* handling result */ }) 9. .catch(err => { /* errors handling */ });
  31. Ревизии документов

  32. Ревизии документов 1. { 2. "_id": "test-doc-1", 3. "_rev": "1-A6157A5EA545C99B00FF904EEF05FD9F",

    4. "content": "Some content" 5. }
  33. Ревизии документов 1. { 2. "_id": "test-doc-1", 3. "_rev": "1-A6157A5EA545C99B00FF904EEF05FD9F",

    4. "content": "Some content" 5. } • Вся история ревизий сохраняется в базе
  34. Ревизии документов 1. { 2. "_id": "test-doc-1", 3. "_rev": "1-A6157A5EA545C99B00FF904EEF05FD9F",

    4. "content": "Some content" 5. } • Вся история ревизий сохраняется в базе • Номер ревизии генерируется автоматически
  35. Ревизии документов 1. { 2. "_id": "test-doc-1", 3. "_rev": "1-A6157A5EA545C99B00FF904EEF05FD9F",

    4. "content": "Some content" 5. } • Вся история ревизий сохраняется в базе • Номер ревизии генерируется автоматически • Для функций put(), post(), remove(), bulkDocs(), и putAttachment() указание ревизии обязательно
  36. Ревизии документов 1. { 2. "_id": "test-doc-1", 3. "_rev": "1-A6157A5EA545C99B00FF904EEF05FD9F",

    4. "content": "Some content" 5. } • Вся история ревизий сохраняется в базе • Номер ревизии генерируется автоматически • Для функций put(), post(), remove(), bulkDocs(), и putAttachment() указание ревизии обязательно
  37. Конфликты и их решения

  38. Типы конфликтов

  39. Типы конфликтов 1. Насильственные (антагонистичные) конфликты 2. Компромиссные конфликты 3.

    Политические конфликты 4. Социальные конфликты 5. Экономические конфликты 6. Организационные конфликты
  40. Типы конфликтов 1. Насильственные (антагонистичные) конфликты 2. Компромиссные конфликты 3.

    Политические конфликты 4. Социальный конфликт 5. Экономические конфликты 6. Организационные конфликты
  41. Типы конфликтов 1. Насильственные (антагонистичные) конфликты 2. Компромиссные конфликты 3.

    Политические конфликты 4. Социальный конфликт 5. Экономические конфликты 6. Организационные конфликты 1. Непосредственные конфликты (Immediate conflicts)
  42. Типы конфликтов 1. Насильственные (антагонистичные) конфликты 2. Компромиссные конфликты 3.

    Политические конфликты 4. Социальный конфликт 5. Экономические конфликты 6. Организационные конфликты 1. Непосредственные конфликты (Immediate conflicts) 2. Возможные конфликты (Eventual conflicts)
  43. Конфликты Непосредственные конфликты

  44. Конфликты • Оптимистическая блокировка Непосредственные конфликты

  45. Конфликты • Оптимистическая блокировка 1. { 2. error: true, 3.

    status: 409, 4. name: 'conflict', 5. message: 'Document update conflict' 6. } Непосредственные конфликты
  46. Оптимистическая блокировка

  47. Оптимистическая блокировка { text: “aaa”, _rev: 1 }

  48. Оптимистическая блокировка { text: “aaa”, _rev: 1 } {text:“aaa”,_rev: 1}

    {text:“aaa”,_rev: 1}
  49. Оптимистическая блокировка { text: “aaa”, _rev: 1 } {text:“bbb”, _rev:

    1}
  50. Оптимистическая блокировка { text: “bbb”, _rev: 2 } OK

  51. Оптимистическая блокировка { text: “bbb”, _rev: 2 } {text:“ccc”, _rev:

    1}
  52. Оптимистическая блокировка { text: “bbb”, _rev: 2 } 409 Conflict

  53. Оптимистическая блокировка { text: “bbb”, _rev: 2 }

  54. Оптимистическая блокировка { text: “bbb”, _rev: 2 } {text:“ccc”, _rev:

    2}
  55. Оптимистическая блокировка { text: “ccc”, _rev: 3 } OK

  56. Конфликты Возможные конфликты

  57. { text: "aaa", _rev: fgf234 } { text: "aaa", _rev:

    fgf234 } Возможные конфликты
  58. { text: "aaa", _rev: fgf234 } { text: "aaa", _rev:

    fgf234 } {text:"bbb", _rev: fgf234} {text:"ccc", _rev: fgf234} Возможные конфликты
  59. { text: "bbb", _rev: ndf12d } { text: "ccc", _rev:

    vba247 } Возможные конфликты
  60. { text: "bbb", _rev: ndf12d } { text: "ccc", _rev:

    vba247 } Возможные конфликты
  61. Конфликты • Автоматическое решение Возможные конфликты

  62. Конфликты • Автоматическое решение • “handles it very elegantly” Возможные

    конфликты
  63. Конфликты • Автоматическое решение • “handles it very elegantly” •

    Возможность решить вручную Возможные конфликты
  64. Конфликты • Автоматическое решение • “handles it very elegantly” •

    Возможность решить вручную 1. db.get(id, {conflicts: true}) Возможные конфликты
  65. Конфликты • Автоматическое решение • “handles it very elegantly” •

    Возможность решить вручную 1. db.get(id, {conflicts: true}) 2. db.get(id, {rev: '8f9asd7s'}) Возможные конфликты
  66. Репликация

  67. Репликация The way I like to think about CouchDB is

    this: CouchDB is bad at everything, except syncing. And it turns out that's the most important feature you could ever ask for, for many types of software. “ Jason Smith Apache CouchDB committer Cloudant developer advocate
  68. Одно- и двунаправленная репликация

  69. Одно- и двунаправленная репликация 1. const localDB = new PouchDB('databaseName');

    2. const remoteDB = new PouchDB('http://domain:5984/dbName');
  70. Одно- и двунаправленная репликация 1. const localDB = new PouchDB('databaseName');

    2. const remoteDB = new PouchDB('http://domain:5984/dbName'); 3. localDB 4. .replicate.to(remoteDB) 5. .on('complete', () => {}) 6. .on('error', (err) => {});
  71. Одно- и двунаправленная репликация 1. const localDB = new PouchDB('databaseName');

    2. const remoteDB = new PouchDB('http://domain:5984/dbName'); 7. localDB 8. .replicate.from(remoteDB) 9. .on('complete', () => {}) 10. .on('error', (err) => {}); 3. localDB 4. .replicate.to(remoteDB) 5. .on('complete', () => {}) 6. .on('error', (err) => {});
  72. Одно- и двунаправленная репликация 1. const localDB = new PouchDB('databaseName');

    2. const remoteDB = new PouchDB('http://domain:5984/dbName'); 7. localDB 8. .replicate.from(remoteDB) 9. .on('complete', () => {}) 10. .on('error', (err) => {}); 11. localDB.sync(remoteDB); 3. localDB 4. .replicate.to(remoteDB) 5. .on('complete', () => {}) 6. .on('error', (err) => {});
  73. Живая репликация

  74. Живая репликация 1. localDB 2. .sync(remoteDB, { live: true, retry:

    true })
  75. Живая репликация 1. localDB 2. .sync(remoteDB, { live: true, retry:

    true }) 3. .on('change', (info) => { 4. /* database content changed within replication */ 5. })
  76. Живая репликация 1. localDB 2. .sync(remoteDB, { live: true, retry:

    true }) 3. .on('change', (info) => { 4. /* database content changed within replication */ 5. }) 6. .on('paused', (err) => { /* replication paused */ })
  77. Живая репликация 1. localDB 2. .sync(remoteDB, { live: true, retry:

    true }) 3. .on('change', (info) => { 4. /* database content changed within replication */ 5. }) 6. .on('paused', (err) => { /* replication paused */ }) 7. .on('active', () => { /* replication resumed */ })
  78. Живая репликация 1. localDB 2. .sync(remoteDB, { live: true, retry:

    true }) 3. .on('change', (info) => { 4. /* database content changed within replication */ 5. }) 6. .on('paused', (err) => { /* replication paused */ }) 7. .on('active', () => { /* replication resumed */ }) 8. .on('denied', (err) => { 9. /* a document failed to replicate */ 10. })
  79. Живая репликация 1. localDB 2. .sync(remoteDB, { live: true, retry:

    true }) 3. .on('change', (info) => { 4. /* database content changed within replication */ 5. }) 6. .on('paused', (err) => { /* replication paused */ }) 7. .on('active', () => { /* replication resumed */ }) 8. .on('denied', (err) => { 9. /* a document failed to replicate */ 10. }) 11. .on('complete', (info) => { /* replication complete*/ })
  80. Живая репликация 1. localDB 2. .sync(remoteDB, { live: true, retry:

    true }) 3. .on('change', (info) => { 4. /* database content changed within replication */ 5. }) 6. .on('paused', (err) => { /* replication paused */ }) 7. .on('active', () => { /* replication resumed */ }) 8. .on('denied', (err) => { 9. /* a document failed to replicate */ 10. }) 11. .on('complete', (info) => { /* replication complete*/ }) 12. .on('error', (err) => { /* errors handling */ });
  81. Необычные репликации

  82. Необычные репликации • In-memory ⇄ Local (кэш)

  83. Необычные репликации • In-memory ⇄ Local (кэш) • Local ⇄

    Local (без сервера)
  84. Необычные репликации • In-memory ⇄ Local (кэш) • Local ⇄

    Local (без сервера) • Remote ⇄ Remote (можно, но не нужно)
  85. Необычные репликации • In-memory ⇄ Local (кэш) • Local ⇄

    Local (без сервера) • Remote ⇄ Remote (можно, но не нужно) • Local ⇄ Remote ⇄ Local (бэкап на сервере)
  86. Map/Reduce функции

  87. Что это?

  88. Что это? • Аналог индексов в SQL базах данных

  89. Что это? • Аналог индексов в SQL базах данных •

    Параллельное выполнение на нескольких узлах
  90. Что это? • Аналог индексов в SQL базах данных •

    Параллельное выполнение на нескольких узлах • Разделяются на два типа:
  91. Что это? • Аналог индексов в SQL базах данных •

    Параллельное выполнение на нескольких узлах • Разделяются на два типа: 1. Временные запросы (Temporary queries)
  92. Что это? • Аналог индексов в SQL базах данных •

    Параллельное выполнение на нескольких узлах • Разделяются на два типа: 1. Временные запросы (Temporary queries) 2. Постоянные запросы (Persistent queries)
  93. Temporary queries

  94. Temporary queries 1. localDB 2. .query( 3. (doc, emit) =>

    emit(doc.name), 4. {key: 'foo'} 5. ) 6. .then((result) => { 7. /* documents with name === 'foo' */ 8. }) 9. .catch((err) => { /* errors handling */ });
  95. Temporary queries 1. localDB 2. .query( 3. (doc, emit) =>

    emit(doc.name), 4. {key: 'foo'} 5. ) 6. .then((result) => { 7. /* documents with name === 'foo' */ 8. }) 9. .catch((err) => { /* errors handling */ }); • Очень медленные запросы
  96. Temporary queries 1. localDB 2. .query( 3. (doc, emit) =>

    emit(doc.name), 4. {key: 'foo'} 5. ) 6. .then((result) => { 7. /* documents with name === 'foo' */ 8. }) 9. .catch((err) => { /* errors handling */ }); • Очень медленные запросы • Рекомендуется использовать только для дебага
  97. Persistent queries

  98. Persistent queries 1. const ddoc = { 2. _id: '_design/my_index',

    3. views: { 4. by_name: { 5. map: function (doc) { 6. emit(doc.name); 7. }.toString() 8. } 9. } 10. };
  99. Persistent queries 1. const ddoc = { 2. _id: '_design/my_index',

    3. views: { 4. by_name: { 5. map: function (doc) { 6. emit(doc.name); 7. }.toString() 8. } 9. } 10. }; 11. pouch 12. .put(ddoc) 13. .then(() => { /* success */ }) 14. .catch((err) => { /* errors handling */ });
  100. Persistent queries 1. localDB 2. .query('my_index/by_name', {key: 'foo'}) 3. .then((res)

    => { /* handle result */ }) 4. .catch((err) => { /* handle error */ });
  101. Persistent queries 1. localDB 2. .query('my_index/by_name', {key: 'foo'}) 3. .then((res)

    => { /* handle result */ }) 4. .catch((err) => { /* handle error */ }); Индексируется только при первом выполнении
  102. Persistent queries 1. localDB 2. .query('my_index/by_name', {key: 'foo'}) 3. .then((res)

    => { /* handle result */ }) 4. .catch((err) => { /* handle error */ }); Индексируется только при первом выполнении 5. localDB 6. .query('my_index/by_name', {limit: 0}) 7. .then((res) => { /* handle result */ }) 8. .catch((err) => { /* handle error */ });
  103. Map-функции

  104. Map-функции 1. function mapFunction(doc) { 2. emit(doc.name); 3. }

  105. Map-функции 1. function mapFunction(doc) { 2. emit(doc.name); 3. } 4.

    function mapFunction(doc) { 5. if (doc.type === 'brick') { 6. if (doc.color === 'blue') { 7. emit('Wow! Blue brick!'); 8. } else { 9. emit(doc.color); 10. } 11. } 12. }
  106. Map-функции

  107. Map-функции 1. pouch 2. .query(mapFunction, {key: 'yellow'}) 3. .then((result) =>

    { /* handle result */ }) 4. .catch((err) => { /* handle errors */ });
  108. Map-функции 1. pouch 2. .query(mapFunction, {key: 'yellow'}) 3. .then((result) =>

    { /* handle result */ }) 4. .catch((err) => { /* handle errors */ }); 5. pouch 6. .query(mapFunction, { 7. startkey: 'C', 8. endkey: 'C\uffff', 9. limit: 5, 10. include_docs: true 11. }) 12. .then((result) => { /* handle result */ }) 13. .catch((err) => { /* handle errors */ });
  109. Reduce-функции

  110. Reduce-функции 1. const mapReduceFun = { 2. map: (doc) =>

    emit(doc.name.charAt(0)), 3. reduce: '_count' 4. };
  111. Reduce-функции 1. const mapReduceFun = { 2. map: (doc) =>

    emit(doc.name.charAt(0)), 3. reduce: '_count' 4. }; 5. pouch.query(mapReduceFun, { 6. key: 'P', 7. reduce: true, 8. group: true 9. }) 10. .then((result) => { /* handle result */ }) 11. .catch((err) => { /* handle errors */ });
  112. Итого

  113. Итого NoSQL база в браузере, в памяти, на сервере, везде

    и всюду
  114. Итого NoSQL база в браузере, в памяти, на сервере, везде

    и всюду Автоматическая синхронизация из коробки
  115. Итого NoSQL база в браузере, в памяти, на сервере, везде

    и всюду Автоматическая синхронизация из коробки Репликация во все стороны из коробки
  116. Итого NoSQL база в браузере, в памяти, на сервере, везде

    и всюду Автоматическая синхронизация из коробки Репликация во все стороны из коробки Интеграция с CouchDB и другими базами данных
  117. Итого NoSQL база в браузере, в памяти, на сервере, везде

    и всюду Автоматическая синхронизация из коробки Репликация во все стороны из коробки Интеграция с CouchDB и другими базами данных Куча плагинов на все случаи жизни
  118. Вопросы Спасибо за внимание @ZurabBelyi BelyiZ BelyiZ