Опции для хранения двоичных плоских файлов только для чтения с использованием Python

StackOverflow https://stackoverflow.com/questions/2256256

Вопрос

Мне было поручено настроить базу данных SKU в виде плоского файла для использования на встроенных устройствах с ограниченным объемом памяти и скоростью процессора.

В основном данные, которые мне нужно сохранить, состоят из следующего:

АРТИКУЛ Описание Расположение Цена Кол-во

Файл будет состоять из нескольких миллионов записей.

Наиболее важными соображениями являются пространство для хранения и время поиска.Записи нужно будет извлекать только по артикулу, и они будут доступны только для чтения, поэтому файл можно отсортировать по артикулу.

Я хотел бы получить доступ к этим данным с помощью Python.Итак, мои вопросы сводятся к следующему.

Существуют ли существующие библиотеки Python, которые могут предоставить мне эту функциональность, или мне нужно создать свою собственную?

Если ответ сводится к тому, чтобы откатить мой собственный, есть ли у кого-нибудь предложения или хорошие рекомендации для этого?

Это было полезно?

Решение

Как насчет Базы данных SQLite с привязками к Python?В нем немного больше, чем вам нужно, но это стандартное программное обеспечение, хорошо протестированное.

Другие советы

Старым способом было бы использовать простую таблицу данных ключ / значение, такую как модуль gdbm.Python поставляется с поддержкой для этого, но он не встроен в установку Python по умолчанию на моем компьютере.

В общем, используйте SQLite.Как писали другие, он входит в стандартную комплектацию Python и уже используется во многих встраиваемых системах.

Если записи имеют фиксированную длину, то вы можете использовать модуль bisect.Размер файла / размер записи указывает количество записей в файле.Поиск по разделению пополам выполнит поиск O (log (n)) в файле, и вам нужно будет написать адаптер для проверки на равенство.Хотя я еще не тестировал это, вот набросок:

import bisect

RECORD_SIZE = 50

class MatchFirst10Chars(object):
    def __init__(self, word):
        self.word = word
    def __lt__(self, other):
        return self.word < other[:10]

class FileLookup(object):
    def __init__(self, f):
        self.f = f
        f.seek(0, 2)
        self.size = f.tell() // RECORD_SIZE
    def __len__(self):
        return self.size

    def __getitem__(self, i):
        self.f.seek(i*RECORD_SIZE)
        return self.f.read(RECORD_SIZE)


SKU = "123-56-89 "
f = open("data_file")
fl = FileLookup(f)
i = bisect.bisect(fl, MatchFirst10Chars(SKU))

Вы могли бы дополнительно заархивировать файл и выполнить поиск в файле gzip'ped, но это компромисс между пространством ивремя, которое вам придется испытать.

Могу я предложить цкб?(Привязки к Python: python-cdb.)

Это формат, используемый для данных, доступных только для чтения, как у вас;по сути, это 256 гигантских хэш-таблиц, каждая из которых может содержать разное количество сегментов.Самое замечательное в cdb то, что файл не нужно загружать в память;он структурирован таким образом, что вы можете выполнять поиск, просто mmapдобавляйте те биты, которые вам нужны.

В спецификация cdb это хорошее чтение, не в последнюю очередь потому, что строки отформатированы таким образом, чтобы создать равномерное правое поле.:-D

Как насчет HDF?Если вам не нужен SQL и вам требуется быстрый доступ к вашим данным, нет ничего быстрее...на языке Python...для числовых или структурированных данных.

Взгляните на Интерфейсы базы данных раздел, посвященный Питон Вики.Это всеобъемлюще.В списке есть пара "чистых" опций Python (например SnakeSQL ( Змеиный sql )), которые немного приятнее развертывать.И, конечно же, всегда есть Беркли , БД и тому подобное, которые очень нежирные и сырые.

Честно говоря, SQLite, вероятно, будет отлично работать для вас.Если вам действительно нужно повысить производительность, то вам следует обратить внимание на формат, основанный на записях, такой как BDB.

Простым решением является Шипучий.Вы также можете найти похожие вопросы на SO.

Вариант ответа Эндрю Далке (чтобы вы все еще могли использовать двоичный поиск для быстрого поиска артикула), который может уменьшить требования к пространству, заключался бы в том, чтобы иметь записи фиксированного размера в начале файла (по одной на артикул), а затем все описания и местоположения (как говорят строки, заканчивающиеся нулем)

Вы экономите место за счет того, что вам не нужно заполнять местоположения и описания до фиксированной длины.Кроме того, вы можете сэкономить место, если есть много повторяющихся местоположений

Вот один из примеров:скажите, что у вас есть

SKU         16 bytes
Description Variable length
Location    Variable length
Price       4 bytes (up to $42949672.95)
Quantity    4 bytes (up to 4294967295)



 offset          SKU        desc_off   loc_off      Price      Quantity
0x00000000 SKU0000000000001 0x01f78a40 0x01f78a47  0x000003e8  0x000f4240
0x00000020 SKU0000000000002 0x01f78a53 0x01f78a59    ...
...
... # 999998 more records
...
0x01f78a40 Widget\x00
0x01f78a47 Head office\x00
0x01f78a53 Table\x00
0x01f78a59 Warehouse\x00
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top