连续规则匹配的模式

时间:2013-01-09 16:17:01

标签: sql design-patterns

我有连续的消息流进行分析。分析返回不同的变量,如作者,主题,情感,单词计数和一组不同的单词。系统中的用户能够定义规则,这些规则应在匹配时触发警报。规则应存储在sql-database中。规则是来自消息分析的单个标准的组合,即word-count > 15 && topic = 'StackOverflow' && sentiment > 2.0 && word-set contains 'great'。在消息分析结束时提供每个允许的规则标准,之后将触发规则验证,并在Java中实现。

必须检查系统中所有用户定义的所有规则的每条消息,这会占用大量的计算能力(目前有10多条消息/秒,并且将有10.000多条要检查的规则)。是否有一个共同的模式来加速匹配过程,也许这样可以并行检查规则,除了一个接一个?是否可以在纯SQL中执行此操作,不同类型的规则的模式如何?

2 个答案:

答案 0 :(得分:2)

您的考虑可能不仅仅是匹配的吞吐量。例如,您需要维护规则。

但是,让我们假设一组静态规则和消息,其中包含满足所有规则所需的所有字段。使用SQL,结构将以message表开头。该表将具有insert触发器。插入触发器将负责匹配规则。这样做的最佳方式是什么?

每秒10条以上的消息,即使每个匹配都是单线程的,您的处理也将具有内在的并行性。我不确定你需要多少努力来并行化比赛。数据库中的并行性通常在SQL语句中而不是在它们之间。

有各种各样的解决方案。例如,您可以将规则编码为巨型存储过程中的代码。这将是一个维持的噩梦,可能会超过存储过程的长度限制,并且可能会非常缓慢。

另一个疯狂的想法。将规则的匹配消息存储在表中,针对该规则,并且只有一个约束加载匹配的消息。然后,您的流程看起来就像是一个无数的插入语句。

更严重的是,您将进一步使用以下代码:

select *
from rules
where . . . 

结果集将具有匹配规则。 where子句可能类似于:

select *
from rules r
where @wordcount > coalesce(r.wordcount, 0) and
      @topic = coalesce(r.topic, @topic) and
      . . .

也就是说,所有规则的每个可能的比较都在where子句中。并且,规则将被预处理以识别他们需要哪些条款。

您甚至可以免除外部变量,并直接访问查询:

select *
from rules r cross join inserted i
where i.wordcount > coalesce(r.wordcount, 0) and
      i.topic = coalesce(r.topic, @topic) and
      . . .

所以,是的,这在SQL中是可行的。而且,您可以并行进行匹配。您只需要以适合数据库比较的格式来处理规则。

答案 1 :(得分:1)

我在C#中解决了类似的问题,但没有使用SQL。

为了便于携带,我将规则作为序列化XML存储在数据库中。

在应用程序启动时,或者规则表发生更改(强制刷新规则缓存)时,我从数据库中加载了所有规则,并将它们反序列化为适当的类。

然后,随着每个应用服务器上的数据进入,我针对传入数据执行了规则,并为执行相应操作的规则传递了规则。 (当时我在应用服务器上执行proc中的操作,但现在我将它转储到队列中。)

这样做的好处是可以在整个应用集群中分散计算,而不是让它在数据库机器上完全消耗周期。