为Web应用程序保留几乎静态数据的最佳方法是什么?

时间:2010-12-27 20:24:33

标签: python data-structures static

我正在python中构建一个Web应用程序。该应用程序的一部分正在处理可以描述如下的数据:

Symbol     Begin Date      End Date
AAPL       Jan-1-1985      Dec-27-2010
...

数据有点静态 - 它会定期更新,即:可以添加新条目,并且可以为所有条目更新“结束日期”字段。

现在,问题是:鉴于数据集的静态性质或多或少,存储它并使用它的最佳方法是什么? “工作”意味着获取随机行,希望每秒多于几次。

我可以使用XML文件,使用SQL DB或SQLite,使用JSON目标文件和内存中的某种python对象。

不同解决方案的缺点和优点是什么?我将感谢解释和边缘情况(例如'直到10次/秒的XML文件是最好的,在SQL DB之后)。

更新:感谢您的所有答案!只是一个小小的更新:目前设置大约3K行。它可能会在一年内增长到15K行。访问模式:对于整套,更新是定期的,每天一次;因此,添加行和更新结束日期都将立即完成。获取随机线确实是符号,可以每秒进行几次。

6 个答案:

答案 0 :(得分:3)

每次数据更改时,我都会生成一个Python源文件,并且该文件主要由字典组成。这假设查找是按符号进行的,并且数据很容易适合内存。

data = {
  "AAPL":       ("Jan-1-1985",      "Dec-27-2010"),
...
}

要批量更新结束日期,请使用pprint.pprint覆盖整个文件。

编辑:为了说明如何编写这样的文件,这里有一个用随机数据填充的脚本

import random, string, pprint

def randsym():
    res =[]
    for i in range(4):
        res.append(random.choice(string.uppercase))
    return ''.join(res)

months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 
          'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']
days = range(1,29)
years = range(1980,2010)
def randdate():
    return "%s-%s-%s" % (random.choice(months),
                         random.choice(days),
                         random.choice(years))

data = {}
for i in range(15000):
    data[randsym()] = (randdate(), "Dec-27-2010")

with open("data.py", "w") as f:
    f.write("data=")
    f.write(pprint.pformat(data))

要访问数据,请执行from data import data

答案 1 :(得分:0)

由于您的数据是高度结构化的,因此XML无用。 CSV和JSON相当快速且易于编辑以满足您的需要。但是,如果您重视一致性(即数据一定不会出错,因为它在读取时已更新),您需要使用file locking来确保一致性。除非您只需要一部分数据并且您的应用程序不能并行运行在多台计算机上,否则我看不到数据库的基本原理。

答案 2 :(得分:0)

按符号获取随机行,而不是大量数据?你需要某种索引。当您启动Web应用程序时,将其存储在从源(csv文件?)读取的python dict中,并在数据更改时重新启动Web应用程序。

按行号获取随机行,而不是大量数据?当您启动Web应用程序时,将其存储在从源(csv文件?)读取的元组的python列表中,并在数据更改时重新启动Web应用程序。

这假定Web应用程序是只读的,并且数据更新是在应用程序外部手动完成的。踢服务器注意更改。

答案 3 :(得分:0)

即使几乎是静态的,您也可能想要排序,搜索和过滤 - 因此它不仅仅是存储。几乎所有read-many-write-once解决方案都会让您满意,包括:

  • SQLite的
  • MySQL的
  • 键/值数据库

索引和其他性能增强取决于您的数据集属性,例如基数,记录数等。您将来是否要在多台计算机之间分配负载?即使对于小型数据集,我也会使用数据库,只是为了更加面向未来,除非它是一个临时应用程序。

答案 4 :(得分:0)

我会避免使用XML,因为它需要更多的解析,而且它的优点不会使表受益。此外,如果您需要的不仅仅是一对一的映射(即AAPL出现两次或更多次),我会避免使用字典。如果数据集相对较小,我建议使用CSV,因为它很容易用作列表:

import csv

myList = []
myReader = csv.reader(open("your_file.csv", "rb"))
for row in reader:
    myList.append(row)
...do stuff...
myWriter = csv.writer(open("your_file.csv", "wb"))
myWriter.writerows(myList)

如果您需要纯粹的速度,效率和可伸缩性,那么无论您选择何种形式,都无法与SQL并行。在各种形式的SQL(MySQL,MSSQL,Postgre等)之间,与一般的SQL和CSV或XML之间的差异相比,差异相对较小。

我说CSV的“相对较小”,因为没有硬性规定可以给你。它取决于许多因素,但在许多系统上通过SQL可能会明显加快几MB以上的任何因素。

答案 5 :(得分:0)

我对这个问题的看法: SQL它可以扩展,大部分工作都是为您处理的。如果你理解SQL,它可能是(98%) 的方式。

CSV文件:一旦您每秒处理多次(12次)访问,这些文件就会变得难看。但是,如果数据的大小合理,请考虑使用ramdrive,您可以将数据分成文件,然后以 blazing 速度访问它们。很多小文件,没问题。但您需要确保需要保存的所有数据都保存在真实磁存储或SSD上。如果数据足够小,您可能正在查看1000次访问的SSD文件/秒。 通过一些良好的文件命名和足够小的数据集,这可能是一个可行的选择。

这里有很多 ifs ,但超快的速度是疯狂可扩展性的折衷,并且为您处理数据一致性。