使用Python的只读二进制平面文件存储选项

1 投票
6 回答
1462 浏览
提问于 2025-04-15 19:13

我被要求为一些存储空间和处理速度有限的嵌入式设备建立一个简单的SKU数据库。

简单来说,我需要存储的数据包括以下内容:

SKU
描述
位置
价格
数量

这个文件将包含几百万条记录。

最重要的考虑因素是存储空间和读取时间。记录只需要通过SKU来检索,并且是只读的,所以文件可以按SKU进行排序。

我想用Python来访问这些数据。所以我的问题就是:

有没有现成的Python库可以帮我实现这个功能,还是说我需要自己动手做一个?

如果答案是需要自己做,有没有人能给我一些建议或者好的参考资料?

6 个回答

1

你觉得 HDF 怎么样?如果你不需要用到SQL,并且想快速访问数据,那在Python中,没有比这个更快的了,特别是对于数值或结构化数据。

可以看看 数据库接口 这个部分,它在 Python 的维基上,内容非常全面。里面列出了一些“纯”Python的选项(比如 SnakeSQL),这些选项部署起来会稍微简单一些。当然,还有 Berkeley DB 之类的,都是非常轻量和原始的选择。

老实说,SQLite 对你来说可能就足够用了。如果你真的需要更高的性能,那你可以考虑像BDB这样的基于记录的格式。

4

以前的方法是使用一个简单的键值数据表,比如 gdbm 模块。Python 自带对这个的支持,但在我电脑上的默认 Python 安装里并没有包含这个。

一般来说,推荐使用 SQLite。正如其他人提到的,它是 Python 的标准库之一,已经在很多嵌入式系统中使用了。

如果记录的长度是固定的,那么你可以使用 bisect 模块。文件大小除以记录大小就能得到文件中的记录数量。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 压缩,然后在压缩后的文件上进行查找,不过这需要你权衡一下空间和时间的取舍,得自己测试一下。

4

你觉得用SQLite配合Python怎么样?虽然它的功能比你需要的多一点,但它是标准软件,经过了很多测试,挺可靠的。

撰写回答