市面上已经有很优秀的嵌入式KV数据库了,如Berkeley DB。为什么还需要把Sqlite当KV数据库用呢?原因若干。
1,可能是为了好玩或者纯属无聊
2,可结合关系型数据库与KV数据库的优点
3,可利用一些sqlite特性做其他KV数据库不好做的事情
4,事务管理更方便
5,sqlite更可靠,更流行
实现思路
使用json(或pickle)dump数据,并将数据写入有KEY(主键)和VALUE两个字段的SQLITE库表中。参照kv数据库调用办法实现外部接口。
主要功能
1,put:写入key/value数据
2,get:获取某个key的value
3,put_many:批量写入key/value数据
4,keys:获取所有key的列表
5,value:获取所有value的列表
6,limit:利用SQL语句中limit关键字,获取数据库中“前”N条KV数据
7,random:利用SQL语句中random关键字,从数据库中随即获取N条KV数据
8,has_key:某个key是否存在
9,cursor_execute:执行sql自定义语句
10,其他:items,pop,filter,count等

代码(KVSqlite.py):

import os, json, sqlite3
from threading import LockPY3 = os.sys.version_info >= (3,)
if PY3:ifilter = filter
else:from itertools import ifilterDUMPS = lambda d: json.dumps(d)
LOADS = lambda d: json.loads(d)class SDB(object):_DEFAULT_TABLE = '__KVS_DEFAULT_TABLE__'_MEMORY_DB = ":memory:"def __init__(self, filename):if filename is None \or len(filename) < 1 \or filename.lower() == self._MEMORY_DB:self.filename = self._MEMORY_DBelse:self.filename = filenameself._lock = Lock()self._db_init()def _row_factory(self, cursor, row):result = []for idx, col in enumerate(cursor.description):if col[0].lower() in ('k', 'v'):result.append(LOADS(row[idx]))else:result.append(row[idx])return resultdef _db_init(self):_new_table = "CREATE TABLE IF NOT EXISTS {0} ( k PRIMARY KEY,v)".format(self._DEFAULT_TABLE)db = sqlite3.connect(self.filename, timeout=60, check_same_thread=False)db.row_factory = self._row_factorydb.execute(_new_table)self._cursor = db.cursor()self._db = dbdef _statement_init(self):table = self._DEFAULT_TABLEreturn dict(insert="insert or replace into {0}(k,v) values(:1,:2)".format(table),delete="delete from {0} where k=:1".format(table),update="update {0} set v=:1 where k=:2".format(table),clear="delete from {0}".format(table),get="select v from {0} where k=:1".format(table),has_key="select count(1) from {0} where k=:1".format(table),keys="select k from {0}".format(table),values="select v from {0}".format(table),items="select k,v from {0}".format(table),count="select count(*) from {0}".format(table),random="select * from {0} order BY RANDOM() limit :1".format(table),limit="select * from {0} limit :1 offset :2".format(table))_statements = property(_statement_init)del _statement_initdef _insert(self, key, value):try:self._lock.acquire(True)self._cursor.execute(self._statements.get('insert'), (DUMPS(key), DUMPS(value)))finally:self._lock.release()def _update(self, key, value):try:self._lock.acquire(True)self._cursor.execute(self._statements.get('update'), (DUMPS(value), DUMPS(key)))finally:self._lock.release()def _delete(self, key):try:self._lock.acquire(True)self._cursor.execute(self._statements.get('delete'), (DUMPS(key),))finally:self._lock.release()def _clear(self):'''删除所有数据:return:'''try:self._lock.acquire(True)self._cursor.execute(self._statements.get('clear'))except Exception as e:self._db.rollback()raise efinally:self._lock.release()def keys(self, sort=False, sort_key=None, reverse=False):if sort:return sorted(self.iterkeys(), key=sort_key, reverse=reverse)return list(self.iterkeys())def values(self, sort=False, sort_key=None, reverse=False):if sort:return sorted(self.itervalues(), key=sort_key, reverse=reverse)return list(self.itervalues())def iterkeys(self):try:self._lock.acquire(True)for k in self._cursor.execute(self._statements.get('keys')):yield k[0]finally:self._lock.release()def itervalues(self):try:self._lock.acquire(True)for v in self._cursor.execute(self._statements.get('values')):yield v[0]finally:self._lock.release()def items(self, sort=False, key=None, reverse=False):if sort:return sorted(self.iteritems(), key=key, reverse=reverse)return list(self.iteritems())def iteritems(self):try:self._lock.acquire(True)for k, v in self._cursor.execute(self._statements.get('items')):yield k, vfinally:self._lock.release()def count(self):try:self._lock.acquire(True)return self._cursor.execute(self._statements.get('count')).fetchone()[0]finally:self._lock.release()def has_key(self, key):try:self._lock.acquire(True)r = self._cursor.execute(self._statements.get('has_key'), (DUMPS(key),)).fetchone()[0]return r > 0finally:self._lock.release()def get(self, key):try:self._lock.acquire(True)_key = DUMPS(key)data = self._cursor.execute(self._statements.get('get'), (_key,)).fetchone()if data:return data[0]finally:self._lock.release()def put(self, key, value):try:self._insert(key, value)self._db.commit()except Exception as e:self._db.rollback()raise edef pop(self, key):try:value = self.get(key)self._delete(key)self._db.commit()return valueexcept Exception as e:self._db.rollback()raise edef put_many(self, rows):try:self._lock.acquire(True)if rows and len(rows) > 0:self._cursor.executemany(self._statements.get('insert'),[(DUMPS(k), DUMPS(v)) for k, v in rows])self._db.commit()except Exception as e:self._db.rollback()raise efinally:if self._lock.locked():self._lock.release()def limit(self, limit=1, offset=0):try:self._lock.acquire(True)rows = self._cursor.execute(self._statements.get('limit'), (limit, offset))if limit == 1:return rows.fetchone()return rows.fetchall()finally:self._lock.release()def random(self, limit=1):try:self._lock.acquire(True)rows = self._cursor.execute(self._statements.get('random'), (limit,))if limit == 1:return rows.fetchone()return rows.fetchall()finally:self._lock.release()def filter(self, func):return list(ifilter(func, self.items()))def ifilter(self, func):return ifilter(func, self.iteritems())def cursor_execute(self, sql, parameters=None):'''执行SQL语句,如:SELECT K,V FROM __KVS_DEFAULT_TABLE__ WHERE K LIKE 'ABC%''''try:self._lock.acquire(True)return self._cursor.execute(sql=sql, parameters=parameters)finally:self._lock.release()def close(self):try:self._db.rollback()self._cursor.close()self._db.close()except:pass

调用示例:

from KVSqlite import SDB
#打开数据库
db = SDB('test.sqlite')
#写入单条数据
db.put('first','第一条数据')
db.put('second',dict(a=1,b=2,c=[2,3,4]))
#获取数据
db.get('first')
#写入多条数据
db.put_many([[1,2],[3,4],['A','abc']])
#获取key的列表
db.keys()

把Sqlite当嵌入式KV数据库用相关推荐

  1. 计划实现一个开源的KV数据库——Simple DB

    实现一个开源KV数据库的想法来源于对目前项目中所使用的K-V数据库使用情况的不满意. 先介绍一下我们的目前项目,作为本文的背景: 较为底层的分布式运行平台,使用C/C++实现的Actor模型(异步消息 ...

  2. sqlite c++插入 timestamp_Dqlite,基于sqlite 高可用(HA)数据库

    原文发表于我的博客, 特此版权声明 noosphere.site: Dqlite,基于sqlite 高可用(HA)数据库 csdn : Dqlite,基于sqlite 高可用(HA)数据库 k3s之前 ...

  3. 大数据入门(SQLite手机本地轻量级数据库增删改查)

    SQLite手机本地轻量级数据库 数据库分为: 1.关系型数据库(mysql主外键属于关系型) 2.对象型数据库(oracle) 3.嵌入式数据库 案例: 安卓控件(5个Button)访问Activi ...

  4. 同时支持三个mysql+sqlite+pdo的php数据库类_同时支持三个MySQL+SQLite+PDO的PHP数据库类...

    PHP学习教程文章简介: 同时支持三个MySQL+SQLite+PDO的PHP数据库类使用方法: // mysql connect $db = new SQL(mysql:host=localhost ...

  5. sqlite管理工具_Liquibase 数据库版本管理工具:1.安装

    1.Liquibase 是什么 粘一段官方的解释 Track, version, and deploy database changes 跟踪.管理和应用数据库变化 说白了,就是一个将你的数据库脚本转 ...

  6. SQLite和NPoco的数据库初始化器

    目录 介绍 IDbInitialiser IDatabaseConfigurator 示例实现 注意事项 下载源代码 - 49.7 KB 介绍 这篇文章是在我创建一个小型博客风格的Web应用程序时出现 ...

  7. typechoSQLIte转MySQL_Typecho SQLite与MySQL的数据库切换及解决MySQL连接打开缓慢问题

    (本科水平,写得不好请不吝指点 ) Ⅰ Abstract Typecho开源轻量级博客系统拥有WordPress主题插件二次开发等一系列优点,但相比于WordPress笨重复杂的操作,Typecho赢 ...

  8. 如何设计一个简单的KV数据库

    下面的内容仅供设计一个简单的KV数据库.如果想要实现一个功能更强的KV数据库的话,还需要考虑:更加丰富的数据类型.数据压缩.过期机制.数据淘汰策略.集群化.高可用等功能,另外还可以增加统计模块.通知模 ...

  9. mysql做kv数据库_如何将SQL数据映射到KV数据库

    日常吐槽 国外文章也不是都是好文章啊,不要见到英文就觉得高大上了-- 前言 越来越多的关系型数据库底层选择基于KV构建,例如TiDB的TiKV(RocksDB),cockroach的levelDB,M ...

最新文章

  1. ps -ef 的含义
  2. spring 定时器任务深入理解
  3. TINYINT,SMALLINT,MEDIUMINT,INT,INTEGER,BIGINT;text,longtext,mediumtext,ENUM,SET等字段类型区别
  4. Star 10.9K!这份Google面试攻略,牛逼了!
  5. spring @Transactional注解参数详解
  6. 一阶网络相应特性的研究_36、 用一阶系统描述的传感器,其动态响应特征的优劣也主要取决于时间常数τ,τ越大越好。( )...
  7. Kali获取不到IP解决方案
  8. C语言大神进来看看这个题目
  9. 美团关联公司公开“无人车及无人配送系统”相关专利
  10. Ant Design Pro引入Echarts 报错Unexpected token
  11. 蓝桥杯 历届试题 剪格子(dfs搜索)
  12. 百度手机输入法,如何使用五笔98版?
  13. leetcode记录-罗马数字转整数
  14. ubuntu上常用的软件安装
  15. Nginx#Nginx-Typora笔记
  16. 15.3,python中扫描条形码和二维码
  17. 导致无线网卡连接不上wifi的几种原因|为什么无线网卡连不上wifi?
  18. 福州黑白风格的婚纱照拍摄介绍
  19. See!AI正在悄然改变着医学诊断、假肢和视觉辅助
  20. wordpress友联_WordPress 友情链接页面终极版

热门文章

  1. 关于开展2022年重庆市第一批高新技术企业认定申报工作的通知
  2. 中地数码:融合创新国产GIS 乘风而上助推实景三维中国建设
  3. centos挂载光驱设备
  4. Verilog HDL 基础
  5. 晶体三极管的三个工作区域及温度对特性的影响
  6. 0324的学习笔记----里面最重要的就是一个tom猫的动画,和涉及到的内存问题(创建imageview的两种方式,imagenamed就会形成缓存,占用很多内
  7. java通过schema校验xml
  8. 基于 SpringBoot + Vue 的学生公寓管理系统
  9. 万能的APT!编译时注解的妙用
  10. 北大计算机图灵班,北京大学举办图灵班开班仪式