无敌的leveldb,可打包进应用的kv数据库

广告位招租
扫码页面底部二维码联系

在研究区块链的过程中,无意得知index【关注微信公众号:wwwtangshuangnet】转载请注明出处:www.tangshuang.netedDB的底层是基于leveldb的,瞬【版权所有,侵权必究】【未经授权禁止转载】间被谷歌大神们的神通吓跪了。在通读了对l原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。eveldb的解释文章之后,发现这类文章转载请注明出处:www.tangshuang.net著作权归作者所有,禁止商业用途转载。根本不适合我这类并不需要对leveldb【访问 www.tangshuang.net 获取更多精彩内容】【关注微信公众号:wwwtangshuangnet】底层了解太多的读者。对于我们前端开发而言转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net,更多要了解的是它怎么用。然而网上对怎么【版权所有】唐霜 www.tangshuang.net【版权所有】唐霜 www.tangshuang.net用反而介绍对少,对它底层的实现介绍的反而【作者:唐霜】本文版权归作者所有,未经授权不得转载。很多。可能是它的底层实现真的太出众了,所未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。以大家都趋之若鹜,而它的api实在是少的本文版权归作者所有,未经授权不得转载。【作者:唐霜】可怜,如果不要什么特别的需求,三个api【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。就够了:put, get, del。为了转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】让前端开发者也有机会使用它,我专门写这篇未经授权,禁止复制转载。【本文受版权保护】文章来对它的使用进行介绍。

【作者:唐霜】【版权所有】唐霜 www.tangshu【未经授权禁止转载】【原创内容,转载请注明出处】ang.net

leveldb简介

LevelDB是Google传奇工程师J转载请注明出处:www.tangshuang.net原创内容,盗版必究。eff Dean和Sanjay Ghem【转载请注明来源】【版权所有】唐霜 www.tangshuang.netawat开源的KV存储引擎(而非SQL)转载请注明出处:www.tangshuang.net原创内容,盗版必究。,它和我介绍过的indexedDB一样,是一种非关系型数据库。然而,它比i未经授权,禁止复制转载。未经授权,禁止复制转载。ndexedDB底层的多,indexed本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。DB有三层概念:database->本文版权归作者所有,未经授权不得转载。【转载请注明来源】;store->objects的概【本文首发于唐霜的博客】【关注微信公众号:wwwtangshuangnet】念,而leveldb只有一层,即obje本文作者:唐霜,转载请注明出处。转载请注明出处:www.tangshuang.netcts,也即key-value。相当于一转载请注明出处:www.tangshuang.net原创内容,盗版必究。个库就是一堆key-value,而由于它未经授权,禁止复制转载。【本文受版权保护】的一个库是对应一个文件目录,所以它其实也转载请注明出处:www.tangshuang.net【版权所有】唐霜 www.tangshuang.net没有库的概念。而最令人喜爱的是,它不需要转载请注明出处:www.tangshuang.net原创内容,盗版必究。依赖任何服务,和sqlite一样,它完全【版权所有,侵权必究】【转载请注明来源】只依赖文件系统,它与redis完全不同,本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】redis是完全依赖内存,并且需要起一个【版权所有,侵权必究】著作权归作者所有,禁止商业用途转载。服务,而leveldb是依赖文件系统,内【作者:唐霜】原创内容,盗版必究。存只是它的一个写操作的中转站,而且它不需原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。要起服务,可以直接打包进应用里面,作为一本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。个应用的内部数据存储引擎。因此,在应用领【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。域,就有了sqlite和leveldb这【本文首发于唐霜的博客】本文版权归作者所有,未经授权不得转载。两个非常不错的选择。

【版权所有】唐霜 www.tangshu【版权所有】唐霜 www.tangshuang.net未经授权,禁止复制转载。ang.net【版权所有】唐霜 www.tangshu著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】ang.net转载请注明出处:www.tangshua【原创内容,转载请注明出处】【作者:唐霜】ng.net转载请注明出处:www.tangshua本文作者:唐霜,转载请注明出处。【版权所有】唐霜 www.tangshuang.netng.net

node项目中使用leveldb

由于leveldb是依赖于文件系统,因此【原创内容,转载请注明出处】【版权所有,侵权必究】,你的程序需要对系统有读写权限,所以我们【未经授权禁止转载】本文作者:唐霜,转载请注明出处。只能在node中使用leveldb。而如【本文受版权保护】【原创内容,转载请注明出处】果你的js代码是运行在browser内,【版权所有】唐霜 www.tangshuang.net【本文受版权保护】那应该使用indexeddb作为代替,毕【版权所有,侵权必究】【版权所有,侵权必究】竟indexeddb底层也是依赖leve著作权归作者所有,禁止商业用途转载。转载请注明出处:www.tangshuang.netldb。

本文版权归作者所有,未经授权不得转载。【版权所有,侵权必究】

在node项目中非常容易使用leveld【转载请注明来源】【关注微信公众号:wwwtangshuangnet】b,通过npm安装:

本文版权归作者所有,未经授权不得转载。【作者:唐霜】【本文受版权保护】
npm install --save level

然后在代码中这样:

【访问 www.tangshuang.n原创内容,盗版必究。本文作者:唐霜,转载请注明出处。et 获取更多精彩内容】【关注微信公众号:wwwtangshua【未经授权禁止转载】原创内容,盗版必究。ngnet】【访问 www.tangshuang.n本文作者:唐霜,转载请注明出处。【转载请注明来源】et 获取更多精彩内容】
import level from "level";
const db = level(__dirname + "/data");
// 写入数据
db.put("key", "value").then(...)
// 读取数据
db.get("key").then(value => {...})
// 删除数据
db.del("key").then(...)

非常简单,而且可以直接使用promise转载请注明出处:www.tangshuang.net【原创不易,请尊重版权】

【版权所有】唐霜 www.tangshu未经授权,禁止复制转载。【未经授权禁止转载】ang.net【原创不易,请尊重版权】

但是和indexedDB相比,它还没有事原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。务,所以要确保数据的顺序操作,必须自己在【原创内容,转载请注明出处】未经授权,禁止复制转载。程序中严格控制代码的位置,以及做各种校验【原创不易,请尊重版权】本文版权归作者所有,未经授权不得转载。。不过你也不用太担心,它有一套日志系统,著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】当你的一个读写操作失败时,它能通过日志系本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。统对你的数据进行复原,不会导致你的数据被原创内容,盗版必究。【本文首发于唐霜的博客】破坏。

【版权所有,侵权必究】【关注微信公众号:wwwtangshua【原创不易,请尊重版权】【本文受版权保护】ngnet】

为leveldb创建索引

很遗憾,leveldb并没有提供索引功能本文作者:唐霜,转载请注明出处。著作权归作者所有,禁止商业用途转载。,它只能通过key值进行查询。level【本文受版权保护】【转载请注明来源】这个package提供来createRe【版权所有】唐霜 www.tangshuang.net本文版权归作者所有,未经授权不得转载。adStream方法,在这个方法里面可以原创内容,盗版必究。【原创不易,请尊重版权】传入options来进行一些控制,但是代转载请注明出处:www.tangshuang.net原创内容,盗版必究。码并不直观。之所以没有提供索引,可能是发原创内容,盗版必究。【版权所有】唐霜 www.tangshuang.net明者觉得就以leveldb的读取性能,完【转载请注明来源】本文版权归作者所有,未经授权不得转载。全可以全量查找,根本用不着建索引。但是这【转载请注明来源】【未经授权禁止转载】样给我们带来了不便,我们习惯用索引去检索转载请注明出处:www.tangshuang.net【原创内容,转载请注明出处】一些非主键的字段。

【转载请注明来源】【原创不易,请尊重版权】【关注微信公众号:wwwtangshua原创内容,盗版必究。【原创内容,转载请注明出处】ngnet】【关注微信公众号:wwwtangshua【未经授权禁止转载】【版权所有,侵权必究】ngnet】

说到这里,有一点:leveldb默认保存转载请注明出处:www.tangshuang.net【本文受版权保护】的不是js对象,而是字符串。如果要保存为转载请注明出处:www.tangshuang.net【作者:唐霜】对象,可以在level函数第二个参数加入{ valueEncoding: "json" }来让保存的js对象以json的形式读取,【访问 www.tangshuang.net 获取更多精彩内容】【版权所有】唐霜 www.tangshuang.net加上之后就像indexedDB一样,写入【本文受版权保护】【本文受版权保护】和读取都像是js的原始对象。

【未经授权禁止转载】【版权所有】唐霜 www.tangshu著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshuangnet】ang.net原创内容,盗版必究。【访问 www.tangshuang.n【未经授权禁止转载】【本文首发于唐霜的博客】et 获取更多精彩内容】

那么到底怎么给leveldb建索引呢?我【本文受版权保护】原创内容,盗版必究。们需要用到一个level-subleve未经授权,禁止复制转载。【版权所有】唐霜 www.tangshuang.netl的package。这个package的本文作者:唐霜,转载请注明出处。【本文受版权保护】作用是在当前数据库的section中建立【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。一个subsection,这就有了ind未经授权,禁止复制转载。本文版权归作者所有,未经授权不得转载。exeddb里面的store的味道,但是原创内容,盗版必究。著作权归作者所有,禁止商业用途转载。还是不同,store里面包含了index【关注微信公众号:wwwtangshuangnet】【版权所有】唐霜 www.tangshuang.net,所以其实store的概念和leveld著作权归作者所有,禁止商业用途转载。著作权归作者所有,禁止商业用途转载。b的库的概念基本同级。

本文作者:唐霜,转载请注明出处。本文作者:唐霜,转载请注明出处。

我们建立一个subsection作为索引【版权所有】唐霜 www.tangshuang.net【访问 www.tangshuang.net 获取更多精彩内容】的存储位置,在这个section里面保存【未经授权禁止转载】【本文受版权保护】索引信息。在按索引检索时,先从这个sec【转载请注明来源】转载请注明出处:www.tangshuang.nettion里面把某一个索引对应的全部值的主本文作者:唐霜,转载请注明出处。【原创内容,转载请注明出处】键找出来,然后通过这些主键,去主sect【作者:唐霜】【作者:唐霜】ion里面把这些所有值找出来。由于lev【访问 www.tangshuang.net 获取更多精彩内容】【作者:唐霜】eldb的读写性能很高,所以基本不用担心本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】这种分两步走的操作。

【原创内容,转载请注明出处】本文版权归作者所有,未经授权不得转载。【本文受版权保护】转载请注明出处:www.tangshua著作权归作者所有,禁止商业用途转载。本文版权归作者所有,未经授权不得转载。ng.net
import level from "level";
import sublevel from "level-sublevel";
export default class LevelDB {
    constructor(options) {
        this.options = options;
        this.path = options.path;
        this.db = sublevel(level(this.path, { valueEncoding: "json" }));
    }
    async index(indexes) {
        this.indexdb = this.db.sublevel("index");
        db.pre(async (input) => {
            let value = input.value;
            let key = input.key;
            if (typeof value !== "object") {
                return;
            }
            for (let index of indexes) {
                if (typeof value[index] !== "undefined") {
                    let prevValue = await this.indexdb.get(index);
                    let newValue = prevValue ? prevValue.concat([key]) : [key];
                    await this.indexdb.put(index + ":" + value[index], newValue);
                }
            }
        });
    }
    put(key, value) {
        return this.db.put(key, value);
    }
    get(key) {
        return this.db.get(key);
    }
    del(key) {
        return this.db.del(key);
    }
    async query(index, value) {
        let results = [];
        let keys = await this.indexdb.get(index + ":" + value);
        if (keys.length) {
            for (let key of keys) {
                let res = await this.db.get(key);
                results.push(res);
            }
        }
        return results;
    }
}

上面是对整个功能的封装,用户可以拿这个类本文版权归作者所有,未经授权不得转载。【原创内容,转载请注明出处】当作leveldb来用,在leveldb【原创内容,转载请注明出处】【本文首发于唐霜的博客】原始三个基础方法上多了index和que著作权归作者所有,禁止商业用途转载。【转载请注明来源】ry两个方法,主要就是针对索引来用的。

【原创不易,请尊重版权】【本文受版权保护】【原创内容,转载请注明出处】【本文受版权保护】

看下具体怎么用:

著作权归作者所有,禁止商业用途转载。【关注微信公众号:wwwtangshua原创内容,盗版必究。本文版权归作者所有,未经授权不得转载。ngnet】【版权所有】唐霜 www.tangshu著作权归作者所有,禁止商业用途转载。本文作者:唐霜,转载请注明出处。ang.net【未经授权禁止转载】
import LevelDB from "./leveldb.class.js";
let db = new LevelDB({ path: __dirname + "/data" });
await db.index([ "name", "age" ]);
await db.put("1001", { id: "1001", name: "lily", age: 10 });
await db.put("1002", { id: "1002", name: "lucy", age: 11 });
let results = await db.query("name", "lily");

需要注意的是,db.query的结果是一原创内容,盗版必究。【访问 www.tangshuang.net 获取更多精彩内容】个数组,这个数组包含了所有key等于va本文作者:唐霜,转载请注明出处。未经授权,禁止复制转载。lue的记录。

转载请注明出处:www.tangshua著作权归作者所有,禁止商业用途转载。【版权所有】唐霜 www.tangshuang.netng.net【转载请注明来源】

将leveldb作为你的应用数据存储引擎

在一些nodejs项目中,例如elect【关注微信公众号:wwwtangshuangnet】【本文首发于唐霜的博客】ron项目中,你不可能要求运行你的应用的【版权所有】唐霜 www.tangshuang.net原创内容,盗版必究。客户机器上一定安装了mysql或者red【版权所有】唐霜 www.tangshuang.net转载请注明出处:www.tangshuang.netis,而如果要安装这些服务,它们本身是项【原创不易,请尊重版权】【原创不易,请尊重版权】目之外的,你不能保证它们安装时的配置是你转载请注明出处:www.tangshuang.net【作者:唐霜】的应用想要的。而如果把数据存储引擎内置在【转载请注明来源】【原创内容,转载请注明出处】项目里面,比如在项目中使用sqlite和本文版权归作者所有,未经授权不得转载。未经授权,禁止复制转载。leveldb,就不需要用户自己去安装其【本文受版权保护】原创内容,盗版必究。他的数据库,同时又能享受到这种数据存储的转载请注明出处:www.tangshuang.net原创内容,盗版必究。便捷。

【原创内容,转载请注明出处】【关注微信公众号:wwwtangshua【关注微信公众号:wwwtangshuangnet】【版权所有,侵权必究】ngnet】

一般而言,在你发布项目代码时,是不应该把转载请注明出处:www.tangshuang.net未经授权,禁止复制转载。数据库产生的具体文件也加入到git中的,【版权所有,侵权必究】本文作者:唐霜,转载请注明出处。用户拿到的,应该是一份干净的应用,只有他【转载请注明来源】【版权所有】唐霜 www.tangshuang.net自己去运行之后,才会产生新的数据。但是在【版权所有,侵权必究】【转载请注明来源】一些特殊情况下,你发布的每一个不同版本的原创内容,盗版必究。【原创不易,请尊重版权】初始数据可能不同,那就有可能直接将数据库本文版权归作者所有,未经授权不得转载。【未经授权禁止转载】文件也打包进你自己的应用中。甚至或者,你【原创不易,请尊重版权】【原创不易,请尊重版权】的应用本身就是需要这些初始数据来作为界面原创内容,盗版必究。【未经授权禁止转载】渲染的前提,比如一些安卓的应用,它们也内原创内容,盗版必究。【本文受版权保护】置来leveldb作为自己的数据存储引擎本文版权归作者所有,未经授权不得转载。【版权所有】唐霜 www.tangshuang.net,它们一开始的时候,机会初始化好数据库,本文作者:唐霜,转载请注明出处。本文版权归作者所有,未经授权不得转载。然后再由用户逐渐写入自己的新数据。

【原创不易,请尊重版权】未经授权,禁止复制转载。著作权归作者所有,禁止商业用途转载。

2018-03-12 24886

为价值买单,打赏一杯咖啡

本文价值248.86RMB