数据库对于在 Node.js 应用程序中持久保存数据至关重要。 根据应用程序的不同,开发者可以采用最多样化的实现,而 Node.js lowdb 是重量级数据库的一个精简替代品,而其也是本文的主角。
数据库的共同点是开发者必须安装数据库软件并运行服务器进程。 然而,在某些情况下,这意味着不必要的大量开销。 特别是如果开发者只是想快速测试某些内容或者处于无法安装任何其他软件的环境中。
SQLite 是一种轻量级替代方案,是基于文件的 SQL 数据库。 但开发者依然必须编译数据库驱动程序。 为了避免这种情况,一个名为 lowdb 的数据库出现了。 lowdb 数据库基于 Lodash ,数据保存在 JSON 文件中。
注意:由于数据库以纯文本形式存储数据,因此根本无法达到成熟数据库的性能,成熟数据库通常以优化的二进制格式存储信息。 因此,不建议在生产操作中使用 lowdb。
什么是 lowdb
lowdb 是简单易用的类型安全的本地 JSON 数据库 ,具有以下突出优势:
非常轻量 极简主义者 支持 TypeScript 纯 JavaScript 安全原子写入 可破解:更改存储、文件格式(JSON、YAML...)或通过适配器添加加密,支持用 lodash、ramda 扩展 在测试期间自动切换到快速内存模式当然,值得一提的是 Lowdb 不支持 Node 的 cluster 模块。
如果有大型 JavaScript 对象(~10-100MB)可能会遇到一些性能问题。 这是因为每当调用 db.write 时,整个 db.data 都会使用 JSON.stringify 序列化并写入存储。
当然,这也和具体用例有关系,可以通过执行批处理操作并仅在需要时调用 db.write 来缓解此问题。如要计划扩展,强烈建议使用 PostgreSQL 或 MongoDB 等数据库。
目前 lowdb 在 Github 通过 MIT 协议开源,有超过 20.5k 的 star、1k 的 fork、422k 的项目依赖量、是一个妥妥的前端优质开源项目。
如何使用 lowdb
Lowdb 是一个纯粹的 ESM 包,下面是基本使用方法:
import {JSONFilePreset} from 'lowdb/node'
// 读取或者创建 db.json
const defaultData = {posts: [] }
const db = await JSONFilePreset('db.json', defaultData)
// 更新 db.json
await db.update(({posts}) => posts.push('hello world'))
// 或者可以稍后显式调用 db.write()
// 写入 db.json
db.data.posts.push('hello world')
await db.write()
输出数据如下:
// db.json
{
"posts": ["hello world"]
}
TypeScript 支持
可以使用 TypeScript 检查数据类型:
type Data = {
messages: string[]
}
const defaultData: Data = {messages: [] }
const db = await JSONPreset<Data>('db.json', defaultData)
db.data.messages.push('foo')
db.data.messages.push(1)
Lodash 扩展
可以使用 Lodash(或其他库)扩展 lowdb。为了能够扩展它,在这里不使用 JSONPreset。相反,使用更加底层的组件。
import {Low} from 'lowdb'
import {JSONFile} from 'lowdb/node'
import lodash from 'lodash'
type Post = {
id: number
title: string
}
type Data = {
posts: Post[]
}
// Extend Low class with a new `chain` field
class LowWithLodash<T> extends Low<T> {
chain: lodash.ExpChain<this['data']> = lodash.chain(this).get('data')
}
const defaultData: Data = {
posts: [],
}
const adapter = new JSONFile<Data>('db.json', defaultData)
const db = new LowWithLodash(adapter)
await db.read()
// Instead of db.data use db.chain to access lodash API
const post = db.chain.get('posts').find({ id: 1 }).value() // Important: value() must be called to execute chain
Lowdb adapters 适配器
JSONFile JSONFileSync
用于读取和写入 JSON 文件的适配器,用法也非常简单:
import {JSONFile, JSONFileSync} from 'lowdb/node'
new Low(new JSONFile(filename), {})
new LowSync(new JSONFileSync(filename), {})
Memory MemorySync
即内存适配器,对于加速单元测试很有用。
import {Memory, MemorySync} from 'lowdb'
new Low(new Memory(), {})
new LowSync(new MemorySync(), {})
LocalStorage SessionStorage
window.localStorage 和 window.sessionStorage 的同步适配器。
import {LocalStorage, SessionStorage} from 'lowdb/browser'
new LowSync(new LocalStorage(name), {})
new LowSync(new SessionStorage(name), {})
本文总结
本文主要和大家介绍 lowdb ,即一个简单易用的类型安全的本地 JSON 数据库。因为篇幅问题,关于 lowdb 只是做了一个简短的介绍,但是文末的参考资料提供了大量优秀文档以供学习,如果有兴趣可以自行阅读。如果大家有什么疑问欢迎在评论区留言。
参考资料
lowdb GitHub地址:https://github.com/typicode/lowdb
https://morioh.com/a/76cb8aa98844/lowdb-simple-to-use-local-json-database
https://headty.medium.com/building-a-crud-app-with-node-express-and-lowdb-beginner-cec2d5d1b65e
https://medium.com/@billys.moustakas/node-js-lowdb-a-lightweight-database-alternative-309583f555b2
https://www.youtube.com/watch?app=desktop&v=jeochJ-hUao
https://morioh.com/a/76cb8aa98844/lowdb-simple-to-use-local-json-database
https://dbdb.io/db/lowdb/revisions/3