2

我有一个非常有趣的任务。但我不知道如何一言以蔽之,以便搜索相关主题。即使这个主题标题也可能无法反映我的需要。所以,如果有人有更好的标题 - 欢迎。

我会试着解释我的问题。

我在 MySQL 数据库表中有大约 100,000 行。我需要“比较”表中的条目。

“比较”并不意味着相等。有计算比较级别的算法。我有每个表格列的权重系数。意味着如果 entry#1 的 column1 等于 entry#2 的 column2,那么我给这对给出 5 个点。每列依此类推。

最直接的方法是为每对条目应用计算规则。我为什么害怕这个?100,000 个条目意味着大约 50 亿次“比较”操作。当然,我可以按需计算并将结果存储在缓存中的某处。但我相信最明显的方法并不是最有效的。

所以,我的第一个问题是:除了蛮力,还有其他更好的方法来实现我的目标吗?

我的第二个问题与更适合计算的工具有关。

  1. 应用程序语言是 PHP。因此,我需要将整个表加载到内存中并迭代数据。
  2. 在 MySQL 中创建存储过程。
  3. 使用 MongoDB 的聚合框架或 MapReduce。

我最不喜欢第一种方式。最重要的是 - 最后一个。

我正在寻找在这种情况下有经验的人的任何建议或建议。

因为,我不知道如何向谷歌寻求帮助,任何链接将不胜感激。

更新:

计算规则比我描述的要复杂一些......

表有一组相关的列,这些列将作为组一次使用(不是一个接一个)。让我们假设:

table有字段,比如说,tag_1, tag_2, .., tag_n. row_1row_2- 中的条目table

规则(伪代码):

if(row_1.tag_1==row_2.tag_1)
{
    // gives 10 points
}
elseif(row_1.tag_1 is in row_2.tags && row_1.tag_1!=row_2.tag_1)
{
    // gives 5 points
}
....
// and so on

基本上,我需要检查两个数组的交集。如果它不是空的 - 给出分数。如果两行中标签的索引匹配,则给出附加点。

我想知道,如何使用存储过程语言来实现这一点?因为使用任何编程语言都可以很容易地完成它。

如果存储过程可以做到这一点,那么这是我的选择。

4

2 回答 2

2

如果您有一个静态表,那么只要您将结果存储在某个地方(大概回到数据库中),您选择的就不会有所不同。

如果您的数据正在发生变化,那么您需要将每个新行与所有行进行比较,这本质上是一次全表扫描。这可能最好在数据库中完成。

如果数据适合内存(并且 500,000 行应该适合内存),那么 (2) 在同等硬件上可能会比 (3) 快。“等效硬件”是一个非常重要的考虑因素。

在大多数情况下,我会选择(2)。听起来查询类似于:

select t.id, t2.id,
       ((case when t1.col1 = t2.col1 then 5 else 0 end) +
        (case when t2.col2 = t2.col2 then 7 else 0 end) +
        . . .
       )
from t cross join t2

如果您对 map-reduce 更满意,那么您可能会发现在那里编写代码更容易。我知道这两种语言,并且更喜欢 SQL 来完成类似的事情。

于 2013-02-12T11:47:07.383 回答
1

你不能做这样的事情:

UPDATE table SET points = points+5 WHERE column1 = column2

如果您也检查特定值,则可以尝试以下操作:

UPDATE table SET points = points+5 WHERE column1 = 'somevalue' AND column2 = 'somevalue'
于 2013-02-12T11:45:05.753 回答