使用 Python 的只读二进制平面文件存储选项
-
20-09-2019 - |
题
我的任务是建立一个平面文件 SKU 数据库,用于存储和处理器速度有限的嵌入式设备。
基本上我需要存储的数据包括以下内容:
SKU描述位置价格数量
该文件将包含数百万条记录。
最重要的考虑因素是存储空间和检索时间。记录只需要按SKU检索,并且是只读的,因此文件可以按SKU排序。
我想用 Python 访问这些数据。所以我的问题归结为这一点。
是否有现有的 Python 库可以为我提供此功能,还是我需要自己构建?
如果答案归结为我自己的,是否有人对此有建议或好的参考?
解决方案
如何的SQLite与Python绑定的?它比你需要多一点,但它的标准软件,并经过严格测试的。
其他提示
旧的方式将是使用一个简单的键/值数据表等GDBM模块。 Python带有的支持,但它没有内置到我的机器上的默认Python安装。
在一般情况下,使用SQLite。正如其他人写的,它带有Python标准,并且它在很多已经嵌入式系统中使用。
如果记录是固定长度,然后可以使用平分模块。文件大小/记录大小给出的文件中的记录数。平分线搜索将执行文件中的一个O(日志(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压缩文件并征询gzip'ped文件,但这是空间与时间,你必须要测试的权衡。
安德鲁Dalke的答案的变化(所以你仍然可以使用二进制搜索快速定位SKU),这可能会降低空间需求将在文件(每个SKU之一)开始有固定大小的记录,然后所有的描述和位置(如空终止字符串说)
您获得通过不必垫出的位置和描述以固定长度以节省空间。您还可以节省空间,如果有很多重复的地点
下面是一个例子: 说你有
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
不隶属于 StackOverflow