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

Python 为web应用程序保留几乎静态数据的最佳方法是什么?,python,data-structures,static,Python,Data Structures,Static,我正在用python构建一个web应用程序。此应用程序的一部分正在处理以下数据: Symbol Begin Date End Date AAPL Jan-1-1985 Dec-27-2010 ... 数据有些静态-它将定期更新,即:可以添加新条目,并且可以为所有条目更新“结束日期”字段 现在的问题是:考虑到数据集或多或少的静态性质,存储和使用它的最佳方式是什么?“工作”意味着获取随机行,希望每秒超过几次 我可以用XML文件、SQL DB或SQLite、J

我正在用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线。比如说,它可能会在一年内增长到1.5万条生产线。访问模式:定期更新,每天一次,用于完整的集合;因此,添加行和更新结束日期都将立即完成。获取随机行实际上是通过符号进行的,每秒可以执行几次。

由于数据是高度结构化的,因此XML没有用处。CSV和JSON速度相当快,易于编辑。但是,如果您重视一致性(即数据在读取时被更新,因此永远不能出错),则需要使用以确保一致性。除非您只需要数据的一个子集,并且您的应用程序不会在多台计算机上并行运行,否则我看不出数据库的基本原理。

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

按行号随机取行,数据不多?启动web应用程序时,将其存储在从源(csv文件?)读取的元组的python列表中,并在数据更改时重新启动web应用程序


这假设web应用程序是只读的,并且数据更新是在应用程序外部手动完成的。让服务器注意到这一变化。

即使几乎是静态的,您也可能需要排序、搜索和筛选,因此不仅仅是存储。几乎任何读多写一次的解决方案都会让您感到高兴,包括:

  • SQLite
  • MySQL
  • 键/值数据库

索引和其他性能增强取决于您的数据集属性,如基数、记录数等。将来是否要在多台计算机之间拆分负载?即使对于小数据集,我也会使用数据库,这只是为了更好地证明未来,除非它是一个特殊的应用程序。

每次数据更改时,我都会生成一个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))

要访问数据,请从数据导入数据执行
,我会避免使用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“相对较小”,因为我没有硬性规定可以给你们。这取决于一系列因素,但在许多系统上,超过几MB的数据可能会通过SQL明显更快。

我对这个问题的看法: SQL在扩展时,大部分工作都是为您处理的。如果您理解SQL,那么可能(98%)就是正确的选择

CSV文件:当你处理每秒超过12次的访问时,这些文件在硬盘上会变得难看。然而,如果数据是合理大小的,考虑使用RAMDRIVER,可以将数据分离成文件,并以惊人的速度访问它们。很多小文件,没问题。但您需要确保所有需要保存的数据都保存在真正的磁性存储器或SSD上。如果数据足够小,SSD上的CSV文件可能每秒访问1000次。 有了一些好的文件命名和足够小的数据集,这可能是一个可行的选择


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

有多少数据?访问模式是什么?嘿,保罗,谢谢你的回答。不,我不需要过滤或排序-这将由另一个数据结构和工作程序完成。你是说只需将对象保留在内存中?我的计算表明,至少在开始的时候,它不应该超过几百K。此外,该应用程序本身不是只读的,尽管它可以被认为是这个特定数据块的RO。这些数据将在主应用程序之外更新。你能详细说明一下吗?如何将数据创建为代码?@Alex:那么请首先详细说明数据是如何给出的。编写文件的一种方法是在文本编辑器中填写它……好吧,在开始时,这可能正是(在编辑器中)要完成的方式。但稍后,它将由某种外部进程进行更新:cron、批处理作业或其他。将此数据保留为所有用户的全局对象将节省大量资源。谢谢,y