1

我的任务是建立一个平面文件 SKU 数据库,用于存储和处理器速度有限的嵌入式设备。

基本上我需要存储的数据包括以下内容:

SKU 描述 地点 价格 数量

该文件将包含数百万条记录。

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

我想用 Python 访问这些数据。所以我的问题归结为这个。

是否有现有的 Python 库可以为我提供此功能,还是我需要自己开发?

如果答案归结为我自己,有没有人有建议或很好的参考?

4

6 回答 6

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 文件并搜索 gzip 文件,但这是您必须测试的空间与时间的权衡。

于 2010-02-13T03:27:19.533 回答
4

带有 Python 绑定的SQLite怎么样?它比您需要的多一点,但它是标准软件并且经过良好测试。

于 2010-02-13T02:27:27.483 回答
1

我可以建议cdb吗?(Python 绑定:python-cdb。)

它是一种用于只读数据的格式,就像您拥有的一样;它基本上是 256 个巨型哈希表,每个哈希表都可以有不同数量的桶。cdb 最酷的地方在于文件不需要加载到内存中;它的结构使您可以通过mmap输入所需的位来进行查找。

cdb规范是一个很好的阅读,尤其是因为这些行被格式化以创建一个统一的右边距。:-D

于 2010-02-13T04:39:32.743 回答
1

HDF怎么样?如果您不需要 SQL 并且需要快速访问您的数据,那么在 Python 中没有比这更快的方法了......对于数字或结构化数据。

查看Python wiki上的DatabaseInterfaces部分。它是全面的。列出了几个“纯” Python 选项(如SnakeSQL),部署起来更好一些。而且,当然,总是有Berkeley DB之类的,它们非常精益和原始。

老实说,SQLite 可能适合你。如果你真的需要寻求更多的性能,那么你会考虑像 BDB 这样的基于记录的格式。

于 2010-02-13T02:30:21.063 回答
0

Andrew 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
于 2010-02-13T04:01:55.393 回答
0

一个简单的解决方案是Cpickle。您还可以在 SO 上找到类似的问题。

于 2010-02-13T02:53:40.143 回答