【问题标题】:What is the best way to keep an almost static data for web application?为 Web 应用程序保留几乎静态数据的最佳方法是什么?
【发布时间】:2010-12-27 20:24:33
【问题描述】:

我正在用 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 行。访问模式:定期更新,每天一次,完整的集合;因此添加行和更新结束日期都将立即完成。确实是通过符号来获取随机行,每秒可以完成几次。

【问题讨论】:

  • 有多少数据?访问模式是什么?

标签: python data-structures static


【解决方案1】:

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

【讨论】:

  • 您能详细说明一下吗?如何将数据创建为代码?
  • @Alex:请先详细说明数据是如何给出的。编写文件的一种方法是在文本编辑器中填写...
  • 好吧,一开始这可能正是它要做的方式(在编辑器中)。但稍后,它将由某种外部进程更新:cron、批处理作业或其他。将此数据保留为所有用户的全局对象将节省大量资源。
  • 谢谢,你的回答是最有用的。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

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

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

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

      【讨论】:

      • 所以你的意思是把对象保存在内存中?我的计算表明它不应该超过几百 K,至少在开始时是这样。此外,该应用程序本身并不是只读的,尽管它可以被视为此特定数据块的 RO。此数据将在主应用程序之外更新。
      【解决方案5】:

      即使几乎是静态的,您也可能想要排序、搜索和过滤 - 所以它不仅仅是存储。几乎任何一次读取多次写入的解决方案都会让您满意,包括:

      • SQLite
      • MySQL
      • 键/值数据库

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

      【讨论】:

      • 嗨,保罗,感谢您的回答。不,我不需要过滤或排序 - 这将由另一个数据结构和工作人员完成。
      【解决方案6】:

      我会避免使用 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 显着加快。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-07-03
        • 1970-01-01
        • 2010-09-13
        • 2018-07-07
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多