Erstens ist bsddb (oder unter seinem neuen Namen Oracle BerkeleyDB) nicht veraltet.
Aus Erfahrung LevelDB/RocksDB/bsddb sind langsamer als wiredtiger, deshalb empfehle ich wiredtiger.
Wiredtiger ist die Speicher-Engine für Mongodb und ist daher in der Produktion gut getestet. Es gibt wenig oder gar keinen Gebrauch von wiredtiger in Python außerhalb meines AjguDB-Projekts; Ich benutze wiredtiger (über AjguDB) um Wikidata und das Konzept zu speichern und abzufragen.
Hier ist eine Beispielklasse, die das Modul python2 shelve imitieren kann. Grundsätzlich es ist ein wiredtiger Backend-Wörterbuch, in dem Schlüssel nur Strings sein:
import json
from wiredtiger import wiredtiger_open
WT_NOT_FOUND = -31803
class WTDict:
"""Create a wiredtiger backed dictionary"""
def __init__(self, path, config='create'):
self._cnx = wiredtiger_open(path, config)
self._session = self._cnx.open_session()
# define key value table
self._session.create('table:keyvalue', 'key_format=S,value_format=S')
self._keyvalue = self._session.open_cursor('table:keyvalue')
def __enter__(self):
return self
def close(self):
self._cnx.close()
def __exit__(self, *args, **kwargs):
self.close()
def _loads(self, value):
return json.loads(value)
def _dumps(self, value):
return json.dumps(value)
def __getitem__(self, key):
self._session.begin_transaction()
self._keyvalue.set_key(key)
if self._keyvalue.search() == WT_NOT_FOUND:
raise KeyError()
out = self._loads(self._keyvalue.get_value())
self._session.commit_transaction()
return out
def __setitem__(self, key, value):
self._session.begin_transaction()
self._keyvalue.set_key(key)
self._keyvalue.set_value(self._dumps(value))
self._keyvalue.insert()
self._session.commit_transaction()
Hier wird das angepasste Testprogramm aus @saaj Antwort:
#!/usr/bin/env python3
import os
import random
import lipsum
from wtdict import WTDict
def main():
with WTDict('wt') as wt:
for _ in range(100000):
v = lipsum.generate_paragraphs(2)[0:random.randint(200, 1000)]
wt[os.urandom(10)] = v
if __name__ == '__main__':
main()
Mit der folgenden Befehlszeile:
python test-wtdict.py & psrecord --plot=plot.png --interval=0.1 $!
Ich habe das folgende Diagramm erstellt:
$ du -h wt
60M wt
Wenn Write-Ahead-Protokoll aktiv ist:
$ du -h wt
260M wt
Dies ist ohne Performance tunning und Kompression.
Wiredtiger hat keine bekannte Grenze bis vor kurzem wurde die Dokumentation der folgenden aktualisiert:
WiredTiger unterstützt Petabyte Tabellen, zeichnet bis zu 4 GB und Rekordzahlen von bis zu 64 Bit.
http://source.wiredtiger.com/1.6.4/architecture.html
SQLite sollte groß arbeiten. Hattest du Probleme damit? Es ist das DBMS, das klein ist, aber die DB selbst kann groß sein. Siehe https://stackoverflow.com/questions/14451624/will-sqlite-performance-degrade-if-the-database-size-is-greater-than-2-gigabytes – Himanshu
@Himanshu Es ist die Tatsache, die Verwendung mit SQLite ist nicht so einfach wie 'db [key] = value' oder' db.put ('key', 'value') ', verwendet aber stattdessen SQL ... Und ich möchte INSERT in TABLE oder SELECT ... für ... vermeiden nur ein einfacher Schlüssel: value 'db [key] = value' set/get. – Basj
Können Sie die Daten mehr beschreiben? 100 GB von was? Wie groß ist der kleinste/mittlere/größte Wert? Wie viele Schlüssel/Wert-Paare bilden die 100 GB? –