存储大型会话级数据集?

时间:2011-09-03 23:28:09

标签: mysql database database-design web-applications search

我正在构建一个由执行以下操作的用户组成的Web应用程序:

  1. 浏览并搜索包含数百万条目的Solr服务器。 (应用程序的这部分工作得非常好。)

  2. 选择此数据的特权部分(某些特定搜索的结果),并暂时将其另存为“数据集”。 (我希望数据集大小仅限于真正大的东西,比如50万个结果。)

  3. 对该数据集执行一些杂项操作。

  4. (前端内置在Rails中,但我怀疑这与如何解决这个特定问题非常相关。)

    第二步,以及如何检索第3步的数据,这给我带来了麻烦。我需要能够暂时保存数据集,在需要时恢复它们,并在一段时间后使它们过期。问题是,我的结果有SHA1校验和ID,因此每个ID为48个字符。即使我只存储ID,500,000记录数据集也是22 MB的数据。所以我不能只有一个数据库表,并为用户构造的每个数据集在其中抛出一行。

    以前有人曾经需要这样的东西吗?解决这个问题的最佳方法是什么?我应该为用户构造的每个数据集生成一个单独的表吗?如果是这样,一段时间后过期/删除这些表的最佳方法是什么?如果需要,我可以部署一个MySQL服务器(虽然我还没有一个,Solr中的所有数据),如果其他东西符合要求,我也会对一些更疯狂的软件开放。

    编辑:一些更详细的信息,以回应Jeff Ferland。

    数据对象是不可变的,静态的,完全驻留在Solr数据库中。它可能比文件更有效,但我更愿意(出于搜索和浏览的原因)将它们保持在原样。数据和数据集都不需要分布在多个系统中,我不指望我们会得到那种负载。现在,整个该死的东西在一个VM内部运行(如果我到达那里,我可以越过那座桥)。

    通过“在需要时恢复”,我的意思是这样的:用户运行一个非常精心设计的搜索查询,从而为他们提供了一组对象。然后他们决定要操纵那套。当他们(作为一个随机的例子)点击“按年划分这些对象”按钮时,我需要能够检索完整的对象ID集,这样我就可以将它们带回Solr服务器并运行更多查询。我宁愿存储对象ID(而不是搜索查询),因为当我们添加更多对象时,结果集可能会在用户下面发生变化。

    “while”大致是用户会话的长度。然而,有一个复杂的问题可能很重要:我可能最终需要实现一个作业队列,以便我可以推迟处理,在这种情况下,“while”需要“只要处理你的工作就需要”。

    感谢Jeff提示我提供正确的进一步细节。

1 个答案:

答案 0 :(得分:2)

第一招:不要将SHA1表示为文本,而是将其占用20个字节。您看到的十六进制值是一种以人类可读形式显示字节的方法。如果你正确地存储它们,那你就是9.5MB而不是22。

其次,你还没有真正解释你所做的事情的性质。您保存的数据集是否引用现有数据库中的不可变对象?在需要时恢复它们是什么意思?当你谈到到期时,“一段时间”有多长?您引用的基础数据是静态还是动态的?您可以保存搜索模式和偏移量,还是需要保存单个参考?

是否需要将与会话相关的数据插入数据库?它可能在文件中更有效吗?这是否需要分布在多个系统中?

我的答案中还有很多问题。为此,您需要更好地表达甚至定义超出您所提供的技术概述的要求。


更新:有很多可能的解决方案。这是两个:

  • 将这些内容写入具有递增搜索ID的单个表(saved_searches等)。按排序顺序插入密钥的加分点。 (search_id unsigned bigint,item_id char(20),主键(search_id,item_id)。这将真正限制碎片,保持每个搜索聚集,并按大致顺序的顺序释放页面。它几乎是一个滚动表,这是关于进行大量插入和删除的最佳情况。在这种情况下,您需要支付插入费用,并将删除费用加倍。您还必须迭代整个搜索结果。
  • 如果您的搜索项具有递增的主ID,那么对数据库的任何新插入将具有比数据库中已有的任何值更高的值,这是最有效的。或者,插入日期戳会以较低的效率实现相同的效果(实际上必须在查询中检查每一行而不仅仅是索引条目)。如果您注意到该最大ID,并且您没有删除记录,那么您可以通过始终在保存的查询上设置最大ID来保存使用零空间的搜索。