python(八):python使用lmdb数据库

您所在的位置:网站首页 python调用info查看数据集 python(八):python使用lmdb数据库

python(八):python使用lmdb数据库

2023-10-04 01:52| 来源: 网络整理| 查看: 265

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 # -*- coding: utf-8 -*- import lmdb    env_db = lmdb.Environment('trainC') # env_db = lmdb.open("./trainC")    txn = env_db.begin()    # get函数通过键值查询数据,如果要查询的键值没有对应数据,则输出None print txn.get(str(200))    for key, value in txn.cursor(): #遍历   print (key, value)    env_db.close() 二、进阶 LMDB 介绍

 

LMDB 全称为 Lightning Memory-Mapped Database,就是非常快的内存映射型数据库,LMDB使用内存映射文件,可以提供更好的输入/输出性能,对于用于神经网络的大型数据集( 比如 ImageNet ),可以将其存储在 LMDB 中。

 

因为最开始 Caffe 就是使用的这个数据库,所以网上的大多数关于 LMDB 的教程都通过 Caffe 实现的,对于不了解 Caffe 的同学很不友好,所以本篇文章只讲解 LMDB。

 

LMDB属于key-value数据库,而不是关系型数据库( 比如 MySQL ),LMDB提供 key-value 存储,其中每个键值对都是我们数据集中的一个样本。LMDB的主要作用是提供数据管理,可以将各种各样的原始数据转换为统一的key-value存储。

 

LMDB效率高的一个关键原因是它是基于内存映射的,这意味着它返回指向键和值的内存地址的指针,而不需要像大多数其他数据库那样复制内存中的任何内容。

 

LMDB不仅可以用来存放训练和测试用的数据集,还可以存放神经网络提取出的特征数据。如果数据的结构很简单,就是大量的矩阵和向量,而且数据之间没有什么关联,数据内没有复杂的对象结构,那么就可以选择LMDB这个简单的数据库来存放数据。

 

LMDB的文件结构很简单,一个文件夹,里面是一个数据文件和一个锁文件。数据随意复制,随意传输。它的访问简单,不需要单独的数据管理进程。只要在访问代码里引用LMDB库,访问时给文件路径即可。

 

用LMDB数据库来存放图像数据,而不是直接读取原始图像数据的原因:

数据类型多种多样,比如:二进制文件、文本文件、编码后的图像文件jpeg、png等,不可能用一套代码实现所有类型的输入数据读取,因此通过LMDB数据库,转换为统一数据格式可以简化数据读取层的实现。 lmdb具有极高的存取速度,大大减少了系统访问大量小文件时的磁盘IO的时间开销。LMDB将整个数据集都放在一个文件里,避免了文件系统寻址的开销,你的存储介质有多快,就能访问多快,不会因为文件多而导致时间长。LMDB使用了内存映射的方式访问文件,这使得文件内寻址的开销大幅度降低。

 

 

LMDB 的基本函数 env = lmdb.open():创建 lmdb 环境 txn = env.begin():建立事务 txn.put(key, value):进行插入和修改 txn.delete(key):进行删除 txn.get(key):进行查询 txn.cursor():进行遍历 txn.commit():提交更改

 

创建一个 lmdb 环境:

# 安装:pip install lmdb import lmdb env = lmdb.open(lmdb_path, map_size=1099511627776)

lmdb_path 指定存放生成的lmdb数据库的文件夹路径,如果没有该文件夹则自动创建。

 

map_size 指定创建的新数据库所需磁盘空间的最小值,1099511627776B=1T。可以在这里进行 存储单位换算。

 

会在指定路径下创建 data.mdb 和 lock.mdb 两个文件,一是个数据文件,一个是锁文件。

 

修改数据库内容:

txn = env.begin(write=True) # insert/modify txn.put(str(1).encode(), "Alice".encode()) txn.put(str(2).encode(), "Bob".encode()) # delete txn.delete(str(1).encode()) txn.commit()

先创建一个事务(transaction) 对象 txn,所有的操作都必须经过这个事务对象。因为我们要对数据库进行写入操作,所以将 write 参数置为 True,默认其为 False。

 

使用 .put(key, value) 对数据库进行插入和修改操作,传入的参数为键值对。

 

值得注意的是,需要在键值字符串后加 .encode() 改变其编码格式,将 str 转换为 bytes 格式,否则会报该错误:TypeError: Won't implicitly convert Unicode to bytes; use .encode()。在后面使用 .decode() 对其进行解码得到原数据。

 

使用 .delete(key) 删除指定键值对。

 

对LMDB的读写操作在事务中执行,需要使用 commit 方法提交待处理的事务。

 

查询数据库内容:

txn = env.begin() print(txn.get(str(2).encode())) for key, value in txn.cursor(): print(key, value) env.close()

每次 commit() 之后都要用 env.begin() 更新 txn(得到最新的lmdb数据库)。

 

使用 .get(key) 查询数据库中的单条记录。

 

使用 .cursor() 遍历数据库中的所有记录,其返回一个可迭代对象,相当于关系数据库中的游标,每读取一次,游标下移一位。

 

也可以想文件一样使用 with 语法:

with env.begin() as txn: print(txn.get(str(2).encode())) for key, value in txn.cursor(): print(key, value)

 

完整的demo如下:

import lmdb import os, sys def initialize(): env = lmdb.open("lmdb_dir") return env def insert(env, sid, name): txn = env.begin(write=True) txn.put(str(sid).encode(), name.encode()) txn.commit() def delete(env, sid): txn = env.begin(write=True) txn.delete(str(sid).encode()) txn.commit() def update(env, sid, name): txn = env.begin(write=True) txn.put(str(sid).encode(), name.encode()) txn.commit() def search(env, sid): txn = env.begin() name = txn.get(str(sid).encode()) return name def display(env): txn = env.begin() cur = txn.cursor() for key, value in cur: print(key, value) env = initialize() print("Insert 3 records.") insert(env, 1, "Alice") insert(env, 2, "Bob") insert(env, 3, "Peter") display(env) print("Delete the record where sid = 1.") delete(env, 1) display(env) print("Update the record where sid = 3.") update(


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3