分类
pouchdb

PouchDB 使用笔记

0. 缘由

我厂的 QA 产品是一个比较重的单页应用,支持用户在本地维护测试用例、执行测试、记录结果,所以需要相对比较复杂的数据存储支持。

首先排除 cookie;localStorage 因为空间有限,也排除了。FileSystem API 不知道目前是个什么状态,不过似乎很少听到它的消息,多半好不到哪儿去,而且明显数据库更适合我,所以最后选定了 IndexedDB

IndexedDB 可以使用不超 1/3 的硬盘空间,大部分场合应该都足够用了。不过 IndexedDB 的 API 层级相对较低,换言之,就是对普通开发者而言,不好用。所以,我选择之前听说过的 PouchDB 作为功能层,提升开发效率。

1. PouchDB 核心功能

首先是存储数取。PouchDB 使用 key-value 存储,然后在上面提供一层类 SQL 查询封装。这套架构已经被 Google 证明性能最好、扩展性最强,比起传统的关系数据库,比如 MySQL,它更容易横向扩展,天生分布式(参考自 Teahour 90 – 和 PingCAP CTO 畅谈数据库和编程语言)。

它的存储结构很像 LeanCloud,每次存储都会生成一个对象,对象里有若干属性。开发中可以很容易的增删属性,表的概念和列的概念在这里并不突出。

下一个重点是同步。PouchDB 完全兼容 CouchDB 协议,而 CouchDB 设计成可以很方便地把数据从一个实例同步到另一个实例。所以我本地使用了 PouchDB,将来就可以利用一个中心仓库在几个不同的实例之间同步代码,或者在本地的几个不同浏览器之间同步代码。

PouchDB 还提供版本管理功能,这点和我之前用过的其它数据库都不太一样。当我们修改对象时,就会生成一个新的版本,还可以回退到之前的版本。这个功能的核心场景我暂时还没太想出来,不过考虑到我们的产品是测试用例编辑器,似乎这个版本管理还的确可以派上些用场。

2. 实例

考虑到将来筛选(query)的需求,每个 PouchDB 实例应该对应一个 MySQL 表,只存放一类内容。

比如 QA,那么就是一个 pouch 实例存储测试用例,一个存储日志。测试用例可能要保留 5+ 个版本历史,日志就不需要版本历史。还有一些别的存储需求,比如测试用例所属的项目(类似打 tag),因为结构非常简单,我考虑用 localStorage 直接存,就不走 PouchDB 了。

3. 同步

PouchDB 实例之间的同步非常简单,只需要一行代码:

const db = new PouchDB('mydb');
// 假设本机启动了 pouchdb-server,端口是 5984
// live 表示当本地 db 发生变化时,自动推送变化到 server
db.replicate.to('http://localhost:5984', {live: true});

// 还可以使用 .sync() 确保 server 的数据能回到本地
// 这对开发过程中修改数据非常有用
db.sync(remoteDB, {live: true});

更完整的文档参考:Replication

4. 最佳实践

官方有一个最佳实践指导,刚开始用,很多地方不是很能理解,不过多看几遍总有好处:12 pro tips for better code with PouchDB

5. 官方文档

链接在此,建议认真阅读。