2012-08-06 6 views
19

私は、スクリプト内のクイックルックアップで利用可能な4億行のユニークなKey-Value情報を持っています。私はこれを行うための滑らかな方法が何だろうと思っています。私は次のことを考慮しましたが、ディクショナリをディスクにマップする方法があり、ディクショナリの作成中以外の多くのメモリを使用しない場合は、わかりません。*クイックルックアップのための永続ストレージを備えた大規模な* Python辞書

  1. 漬け辞書オブジェクト:理想的に単純に数値であるサードパーティのものに加えて、キーと値の最小の依存性を持っている何かをしたい:これは
  2. のNoSQL型dbasesは私の問題のための最適なソリューションであるかどうかわかりません。これがまだ最高の選択肢だと思えば、私もそれを聞きたいと思います。それは私を納得させるかもしれない。

明確でないことがあれば教えてください。

ありがとうございます! -Abhi

+15

persistence = databaseの大きい辞書。 –

+0

私はcouch-dbがこの種のもののために非常に便利だと聞いたことがあります(しかし、それを使う必要はありませんでした)... –

答えて

16

大規模な辞書を永続化する場合は、基本的にデータベースを参照しています。

Pythonには、sqlite3のサポートが組み込まれており、ディスク上のファイルに基づいた簡単なデータベースソリューションを提供します。

+0

DNAの大きな配列や何かのものに対してデータベースを使う他の質問へのリンクを見つける必要があります。 –

+0

OKこれは役に立ちました – Abhi

+1

これを実装し、私たちが必要とするスピードでうまく動作します:) – Abhi

4

私はあなたがpickled dictを試すべきだとは思わない。私は、Pythonが毎回全部をスラップすることを確信しています。つまり、あなたのプログラムはおそらく必要以上にI/Oを待つでしょう。

これは、データベースが発明された問題の種類です。あなたは "NoSQL"を考えていますが、SQLデータベースも機能します。このためにSQLiteを使用できるはずです。私は大規模なSQLiteデータベースを作成したことはありませんが、SQLiteの制限についてのこの議論によれば、4億件のエントリは大丈夫です。 (私の意見では)間違いなく

What are the performance characteristics of sqlite with very large database files?

+0

SQLはうまくいくかもしれませんが、やりすぎです。 – LtWorf

+1

SQLiteは本当に "過剰な"ものではありません。非常に多くのプロジェクトで使用されている理由があります。 – steveha

5

あなたはこれが持続する場合、その後、Redisのは素晴らしい選択肢です。

  1. インストールのRedisサーバ
  2. スタートRedisのサーバー
  3. 利益(のRedisをインストールPIP)のRedisのpython可能パッケージをインストールします。

import redis 

ds = redis.Redis(host="localhost", port=6379) 

with open("your_text_file.txt") as fh: 
    for line in fh: 
     line = line.strip() 
     k, _, v = line.partition("=") 
     ds.set(k, v) 

上記のような値のファイルを前提としています

key1=value1 
key2=value2 
etc=etc 

は、あなたのニーズに挿入スクリプトを変更します。


import redis 
ds = redis.Redis(host="localhost", port=6379) 

# Do your code that needs to do look ups of keys: 
for mykey in special_key_list: 
    val = ds.get(mykey) 

は、なぜ私はRedisのが好きです。原則として

  1. 設定可能な持続性オプション
  2. だけのキー/値ペア(他のデータ型)以上のものを提供しています驚くほど速い
  3. @antrirez
+0

あなたが他のキーバリューストアのデータベースと遊んでいて、何か言いたいものがあるのだろうかと思っています。ありがとうございました – Abhi

11

shelveモジュールは、正確に何をしたいん。これは、データベースファイルによってバックアップされた永続的な辞書を提供します。キーは文字列でなければなりませんが、shelveはpickling/unpickling値を処理します。 dbファイルのタイプはさまざまですが、軽量のキー値データベースであるBerkeley DBハッシュにすることができます。

あなたのデータサイズは膨大に聞こえるので、いくつかのテストを行う必要がありますが、shelve/BDBはおそらくそれに依存しています。

注:bsddbモジュールは推奨されていません。可能であれば、shelveは将来BDBハッシュをサポートしません。

7

誰もdbmについて言及していません。これはファイルのように開かれ、辞書のように振る舞い、標準的な分布になっています。ドキュメントから

http://docs.python.org/release/3.0.1/library/dbm.html

import dbm 

# Open database, creating it if necessary. 
db = dbm.open('cache', 'c') 

# Record some values 
db[b'hello'] = b'there' 
db['www.python.org'] = 'Python Website' 
db['www.cnn.com'] = 'Cable News Network' 

# Note that the keys are considered bytes now. 
assert db[b'www.python.org'] == b'Python Website' 
# Notice how the value is now in bytes. 
assert db['www.cnn.com'] == b'Cable News Network' 

# Loop through contents. Other dictionary methods 
# such as .keys(), .values() also work. 
for k, v in db.iteritems(): 
print(k, '\t', v) 

# Storing a non-string key or value will raise an exception (most 
# likely a TypeError). 
db['www.yahoo.com'] = 4 

# Close when done. 
db.close() 

私はより多くのエキゾチックな形態のいずれかの前にこれをしようとするだろう、と棚/ピクルスを使用すると、負荷にメモリにすべてを引っ張ってきます。

乾杯

ティム

+1

以前のバージョンのPythonでは、これは 'anydbm'モジュールでした。 –

2

私は個人的には数万のレコードDBのためLMDBとそのpython bindingを使用しています。 RAMより大きいデータベースの場合でも非常に高速です。 これはプロセスに組み込まれているため、サーバーは必要ありません。 依存関係はpipで管理します。

唯一の欠点は、DBの最大サイズを指定する必要があることです。 LMDBはこのサイズのファイルをmmapします。小さすぎる場合は、新しいデータを挿入するとエラーが発生します。大きくするには、スパースファイルを作成します。

関連する問題