Подтвердить что ты не робот

* большой * словарь python с хранилищем сохраняемости для быстрого поиска

У меня есть 400 миллионов строк уникальной информации о ключевом значении, которую я хотел бы получить для быстрого поиска в script. Мне интересно, что бы это было так. Я рассмотрел следующее, но не уверен, есть ли способ на диске отобразить словарь и не использовать много памяти, кроме как при создании словаря.

  • маринованный объект словаря: не уверен, что это оптимальное решение для моей проблемы.
  • dbases типа NoSQL: в идеале требуется что-то, что имеет минимальную зависимость от стороннего материала плюс ключевое значение - просто цифры. Если вы считаете, что это по-прежнему лучший вариант, я тоже хотел бы услышать это. Может быть, это меня убедит.

Пожалуйста, дайте мне знать, если что-то неясно.

Спасибо! -Abhi

4b9b3361

Ответ 1

Если вы хотите сохранить большой словарь, вы в основном смотрите на базу данных.

Python поставляется со встроенной поддержкой sqlite3, что дает вам легкое решение для базы данных, поддерживаемое файлом на диске.

Ответ 2

В принципе модуль shelve делает именно то, что вы хотите. Он обеспечивает постоянный словарь, поддерживаемый файлом базы данных. Ключи должны быть строками, но полка будет заботиться о значениях травления/распиловки. Тип файла db может различаться, но он может быть хешем Berkeley DB, который является отличной базой для базы данных с легким весом.

Ваш размер данных звучит огромно, поэтому вы должны провести некоторое тестирование, но shelve/BDB, вероятно, зависит от него.

Примечание. Модуль bsddb устарел. Возможно, полка не будет поддерживать хеши BDB в будущем.

Ответ 3

Никто не упомянул 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()

Я попробовал бы это перед любой из более экзотических форм, а использование shelve/pickle потянет все в память при загрузке.

Приветствия

Тим

Ответ 4

Без сомнения (по-моему), если вы хотите, чтобы это продолжалось, Redis - отличный вариант.

  • Установить redis-сервер
  • Запустить сервер redis
  • Установить redis python pacakge (pip install redis)
  • Profit.

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

Измените вставку script в соответствии с вашими потребностями.


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.

  • Настраиваемые параметры устойчивости
  • Блестяще быстро
  • Предлагает больше, чем просто пары ключ/значение (другие типы данных)
  • @antrirez

Ответ 5

Я не думаю, что вы должны попробовать маринованный дикт. Я уверен, что Python будет каждый раз обрабатывать все это, что означает, что ваша программа будет ждать ввода-вывода дольше, чем это возможно.

Это та проблема, для которой были изобретены базы данных. Вы думаете "NoSQL", но SQL-база данных тоже будет работать. Вы должны использовать SQLite для этого; Я никогда не делал базу данных SQLite большой, но в соответствии с этим обсуждением ограничений SQLite 400 миллионов записей должны быть в порядке.

Каковы характеристики производительности sqlite с очень большими файлами базы данных?

Ответ 6

Я лично использую LMDB и привязку python для несколько миллионов записей DB. Это чрезвычайно быстро даже для базы данных, большей, чем оперативная память. Он встроен в процесс, поэтому сервер не нужен. Зависимость управляется с помощью pip.

Единственным недостатком является то, что вы должны указать максимальный размер БД. LMDB собирается в mmap файл такого размера. Если слишком мало, вставка новых данных вызовет ошибку. В целом вы создаете разреженный файл.