25

スクリプトですばやく検索できるようにしたい4億行の一意のキー値情報があります。私はこれを行うための巧妙な方法は何でしょうか。私は次のことを検討しましたが、辞書の作成中を除いて、多くのメモリを使用せずに辞書をディスクマップする方法があるかどうかはわかりませんでした。

  1. 漬け辞書オブジェクト:これが私の問題の最適な解決策であるかどうかわからない
  2. NoSQLタイプのdbases:理想的には、サードパーティのものへの依存度が最小限で、キー値が単純な数値であるものが必要です。これがまだ最善の選択肢だと思われる場合は、それもお聞きしたいと思います。それは私を納得させるかもしれません。

不明な点がありましたらお知らせください。

ありがとう!-アビ

4

6 に答える 6

20

大きなディクショナリを保持したい場合は、基本的にデータベースを見ています。

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

于 2012-08-06T23:15:43.637 に答える
13

誰もdbmについて言及していません。ファイルのように開かれ、辞書のように動作し、標準配布されています。

ドキュメントからhttps://docs.python.org/3/library/dbm.html

import dbm

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

    # 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'

    # Often-used methods of the dict interface work too.
    print(db.get('python.org', b'not present'))

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

# db is automatically closed when leaving the with statement.

よりエキゾチックなフォームの前にこれを試してみます.shelf/pickleを使用すると、ロード時にすべてがメモリに取り込まれます.

乾杯

ティム

于 2012-08-07T01:05:41.303 に答える
13

原則として、shelveモジュールはまさにあなたが望むことを行います。データベース ファイルに基づく永続的な辞書を提供します。キーは文字列でなければなりませんが、値のピクル/アンピクルは shelve が処理します。db ファイルのタイプはさまざまですが、優れた軽量のキー値データベースであるBerkeley DBハッシュにすることができます。

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

注: bsddbモジュールは廃止されました。shelve は将来的に BDB ハッシュをサポートしなくなる可能性があります。

于 2012-08-07T00:01:41.040 に答える
5

間違いなく (私の意見では)、これを維持したい場合は、Redis が優れたオプションです。

  1. redis-server をインストールする
  2. redis サーバーを起動する
  3. redis python パッケージをインストールします (pip install redis)
  4. 利益。

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. キーと値のペアだけではありません (他のデータ型)
  4. @アントリレス
于 2012-08-06T23:20:49.487 に答える
4

酢漬けの口述を試してはいけないと思います。私は、Python が毎回すべてを丸呑みすることを確信しています。つまり、プログラムはおそらく必要以上に長く I/O を待機することになります。

これは、データベースが発明された種類の問題です。「NoSQL」と考えていますが、SQL データベースも機能します。これには SQLite を使用できるはずです。これほど大きな SQLite データベースを作成したことはありませんが、SQLite の制限に関するこの説明によると、4 億エントリは問題ないはずです。

非常に大きなデータベース ファイルを持つ sqlite のパフォーマンス特性は何ですか?

于 2012-08-06T23:17:05.053 に答える
3

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

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

于 2016-05-11T09:17:38.987 に答える