LMDB

学习LMDB的时候不禁想到知乎上的提问“有哪些名人长期生活在其他名人的光环下”,说实话感觉查它的人基本都是为了用Caffe……

Anyway,LMDB和SQLite/MySQL等关系型数据库不同,属于key-value数据库(把LMDB想成dict会比较容易理解),键key与值value都是字符串。

安装:

pip install lmdb

使用时import lmdb。

2 操作流程

概况地讲,操作LMDB的流程是:

  • 通过env = lmdb.open()打开环境
  • 通过txn = env.begin()建立事务
  • 通过txn.put(key, value)进行插入和修改
  • 通过txn.delete(key)进行删除
  • 通过txn.get(key)进行查询
  • 通过txn.cursor()进行遍历
  • 通过txn.commit()提交更改

4.3 操作实例

4.3.1 建立环境
#!/usr/bin/env python

import lmdb

env = lmdb.open("students");

运行一下,查看当前目录的变化:

1240

set_env.py

可以看到当前目录下多了students目录,里面有data.mdb和lock.mdb两个文件。

4.3.2 插入、删除、修改

插入与修改都用put实现,删除用delete实现。

#!/usr/bin/env python

import lmdb

env = lmdb.open("students");
txn = env.begin(write = True);

txn.put(str(1), "Alice");
txn.put(str(2), "Bob");
txn.put(str(3), "Peter");

txn.delete(str(1));

txn.put(str(3), "Mark");

txn.commit();

注意用txn = env.begin()创建事务时,有write = True才能够写数据库。

4.3.3 查询

查单条记录用get(key),遍历数据库用cursor。

直接在上面的代码commit()之后加上:

txn = env.begin();
print txn.get(str(2));

for key, value in txn.cursor():
    print (key, value);

运行一下,输出结果为:

1240

test_query.py

注意上次commit()之后要用env.begin()更新txn。

4.3.4 完整的例子
#!/usr/bin/env python

import lmdb
import os, sys

def initialize():
    env = lmdb.open("students");
    return env;

def insert(env, sid, name):
    txn = env.begin(write = True);
    txn.put(str(sid), name);
    txn.commit();

def delete(env, sid):
    txn = env.begin(write = True);
    txn.delete(str(sid));
    txn.commit();

def update(env, sid, name):
    txn = env.begin(write = True);
    txn.put(str(sid), name);
    txn.commit();

def search(env, sid):
    txn = env.begin();
    name = txn.get(str(sid));
    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(env, 3, "Mark");
display(env);

print "Get the name of student whose sid = 3."
name = search(env, 3);
print name;

env.close();

os.system("rm -r students");

运行一下,输出结果为:

1240

test_lmdb.py


 

文/kophy(简书作者)
原文链接:http://www.jianshu.com/p/66496c8726a1
著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。

转载于:https://my.oschina.net/lCQ3FC3/blog/758941

### LMDB数据库的基本配置与使用方法 LMDB(Lightning Memory-Mapped Database)是一种轻量级的嵌入式键值数据库,具有高性能和低资源消耗的特点。其结构简单,仅包含一个数据文件和一个锁文件,支持快速访问且无需独立的数据库管理进程。只要在代码中引入 LMDB 库,并指定数据库文件路径即可直接使用[^1]。 #### 创建和打开数据库环境 LMDB 的核心是 `lmdb.Environment` 类,用于管理数据库环境。创建数据库环境时需要指定一个目录路径,该目录下将生成数据文件和锁文件。 ```python import lmdb # 创建数据库环境 env = lmdb.open('./mydb', map_size=10485760) # map_size 单位为字节 ``` 上述代码创建了一个名为 `mydb` 的数据库目录,`map_size` 参数定义了数据库的最大容量。该参数应根据实际数据量进行调整,以避免频繁扩展带来的性能损耗。 #### 数据的读写操作 在 LMDB 中,所有数据操作都必须通过 `lmdb.Transaction` 实例完成。写操作需在写事务中进行,读操作可在读事务中完成。 ```python with env.begin(write=True) as txn: # 写入数据 txn.put(b'key1', b'value1') txn.put(b'key2', b'value2') with env.begin() as txn: # 读取数据 value = txn.get(b'key1') print(value) # 输出: b'value1' ``` 上述代码展示了如何使用事务进行数据写入和读取。写事务通过 `begin(write=True)` 启动,读事务则默认启动。`put` 方法用于写入键值对,`get` 方法用于根据键获取对应的值。 #### 使用游标遍历数据库 若需遍历整个数据库,可以使用 `lmdb.Cursor` 对象。游标允许逐条访问键值对,适用于批量处理或数据分析场景。 ```python with env.begin() as txn: cursor = txn.cursor() for key, value in cursor: print(f'{key}: {value}') ``` 游标遍历操作是按自然排序进行的,键值对按字典序排列,因此适合有序访问。 #### 在深度学习中的应用 LMDB 常用于深度学习任务中,特别是在图像数据集的管理方面。由于其内存映射机制,LMDB 可以高效地加载大规模图像数据,从而提升训练效率。例如,在 PyTorch 中,可以通过 `torchvision.io` 或自定义数据加载器与 LMDB 结合使用,实现快速数据读取[^3]。 ```python from torch.utils.data import Dataset, DataLoader import lmdb import pickle class LmdbDataset(Dataset): def __init__(self, db_path): self.env = lmdb.open(db_path, readonly=True, lock=False) with self.env.begin() as txn: self.length = txn.stat()['entries'] def __len__(self): return self.length def __getitem__(self, idx): with self.env.begin() as txn: key = f'{idx}'.encode() data = txn.get(key) return pickle.loads(data) ``` 上述代码定义了一个基于 LMDB 的 PyTorch 数据集类,支持与 `DataLoader` 配合使用,实现多线程数据加载。 #### 安全性与并发控制 LMDB 支持多线程和多进程访问,读操作可以并发进行,写操作则采用写锁机制,确保数据一致性。在多线程环境下,建议将写操作集中处理,避免频繁切换事务状态。 ```python # 多线程读取示例 from concurrent.futures import ThreadPoolExecutor def read_key(key): with env.begin() as txn: return txn.get(key) with ThreadPoolExecutor() as executor: results = list(executor.map(read_key, [b'key1', b'key2'])) ``` 上述代码使用了 `ThreadPoolExecutor` 实现并发读取,每个线程开启独立的只读事务,确保线程安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值