2006-12-30
规则引擎数据库实现的一个设想
关键字: rule engine
看了jbossrules是实现是把规则写在一个文本文件中,然后解析翻译这个文件。规则被分成when .. then..两个部分。这种实现方式的好处是规则的变化、书写很灵活,并且和java代码很容易结合起来,但是问题是规则文件不能由系统的最终用户来编写。
有没有可能把规则用数据库来表达呢,这样就很容易针对这几张表做一个crud的操作,给最终用户一个操作界面就能维护规则了,目前没有这种把规则定义在数据库的规则引擎,不知道有没有,是否是相对于文件形式弊端太多。我的想法如下:
规则分成两部分,在jbossrules中是lhs,rhs,即左手边条件,右手边结果。条件可以理解为某个项目的取值,取值有两种情况:连续值和离散值,比如工资是个连续值,性别是离散值;结果可转化为一个数值,比如打折的折扣规则最终要的结果就是一个折扣比率,如果结果要求的是等级的划分,也可以用数值来编码,比如1代表贵宾客户,2代表普通客户。
这样规则表就分连续规则表和离散规则表两种
连续规则表:
项目 下限 下限开闭 上限 上限开闭 结果
-------------------------------------------------------------------------
工资 1000 开 2000 闭 5
工资 2000 开 3000 闭 10
上面这两条记录表示工资(1000,2000] 积分算5分,工资在(2000,3000]这个区间积分算10分。下限为空时表示没有下限,上限同理。
离散规则表:
项目 取值 结果
-----------------------------
性别 男 5
性别 女 10
上面两条记录表示性别取值是男、女分别积分算5分、10分。
一条规则由N个“项目”组成,这些“项目”就是jbossrules中的fact的度量值,比如工资、性别等等。所以规则表如下:
规则表:
规则id 项目 离散/连续
------------------------------------
1 工资 连续
1 性别 离散
这个规则表示由两个项目组成。当一个业务行为的数据传进来比如一个工资为1800男性客户需要计算他的积分,则把规则id为 1的积分规则所有项目与规则表的项目关联,分别累加每个项目的积分值得到总和。
这种想法可行吗?
有没有可能把规则用数据库来表达呢,这样就很容易针对这几张表做一个crud的操作,给最终用户一个操作界面就能维护规则了,目前没有这种把规则定义在数据库的规则引擎,不知道有没有,是否是相对于文件形式弊端太多。我的想法如下:
规则分成两部分,在jbossrules中是lhs,rhs,即左手边条件,右手边结果。条件可以理解为某个项目的取值,取值有两种情况:连续值和离散值,比如工资是个连续值,性别是离散值;结果可转化为一个数值,比如打折的折扣规则最终要的结果就是一个折扣比率,如果结果要求的是等级的划分,也可以用数值来编码,比如1代表贵宾客户,2代表普通客户。
这样规则表就分连续规则表和离散规则表两种
连续规则表:
项目 下限 下限开闭 上限 上限开闭 结果
-------------------------------------------------------------------------
工资 1000 开 2000 闭 5
工资 2000 开 3000 闭 10
上面这两条记录表示工资(1000,2000] 积分算5分,工资在(2000,3000]这个区间积分算10分。下限为空时表示没有下限,上限同理。
离散规则表:
项目 取值 结果
-----------------------------
性别 男 5
性别 女 10
上面两条记录表示性别取值是男、女分别积分算5分、10分。
一条规则由N个“项目”组成,这些“项目”就是jbossrules中的fact的度量值,比如工资、性别等等。所以规则表如下:
规则表:
规则id 项目 离散/连续
------------------------------------
1 工资 连续
1 性别 离散
这个规则表示由两个项目组成。当一个业务行为的数据传进来比如一个工资为1800男性客户需要计算他的积分,则把规则id为 1的积分规则所有项目与规则表的项目关联,分别累加每个项目的积分值得到总和。
这种想法可行吗?
- 09:02
- 浏览 (9138)
- 论坛浏览 (9918)
- 评论 (25)
- 分类: Programming
- 相关推荐
评论
eyejava 写道
我的想法不是把规则用数据库存储起来,那样有什么意义?
最终目的是通过web页面能让最终用户定义自己的规则,这个定义的过程不是在文本框里面写 a >20 && b <30 之类的表达式,对于最终用户,让他们写这些很简单的表达式都是恶梦。
最终目的是通过web页面能让最终用户定义自己的规则,这个定义的过程不是在文本框里面写 a >20 && b <30 之类的表达式,对于最终用户,让他们写这些很简单的表达式都是恶梦。
你的表结构和业务太相关了,如果业务发生变化可能会有你的表结构不支持的情况发生。
例:
when
sample : Sample()
parameter : Parameter()
eval(sample.getA() < parameter.getUpper())
eval(sample.getA() > parameter.getLower())
then
sample.setResult(parameter.getResult());
如果多加了其他值得判断比如!=null你的表结构如何支持?
我的想法不是把规则用数据库存储起来,那样有什么意义?
最终目的是通过web页面能让最终用户定义自己的规则,这个定义的过程不是在文本框里面写 a >20 && b <30 之类的表达式,对于最终用户,让他们写这些很简单的表达式都是恶梦。
最终目的是通过web页面能让最终用户定义自己的规则,这个定义的过程不是在文本框里面写 a >20 && b <30 之类的表达式,对于最终用户,让他们写这些很简单的表达式都是恶梦。
江南白衣 写道
yimlin 写道
eyejava 写道
那我把ss1.0弄来参考一下,drools本身也有这个模块,好像。但是现在上不了他的网站,闷的慌。
springside1.0m3的下载也在sf上,yimlin能帮忙传一份到javaeye的ftp上吗,依赖的是drools 2.5?
springside1.0m3的下载也在sf上,yimlin能帮忙传一份到javaeye的ftp上吗,依赖的是drools 2.5?
我现在没有这块代码,而且依赖2.5!建议还是用3.0毕竟支持dsl。
数据库存储规则是十分必需的,起码可以作规则更改的审计,ss2.0 不做这块是因为drools 3.0自己的road map里有这部分,怕做了无用功,否则anders小明出手作一下估计也不用多少时间:)
除非真的有规则更改审批或是集群的需求,要不然我觉得规则本身用数据库存储没有什么意义。
想象一下没有IDE支持的规则修改以及规则修改后的单元测试就很让人头大了。
哪怕不得不用数据库维护,我觉得修改和测试在开发环境使用drl,通过接口同步到实际环境的数据库进行规则审批。
yimlin 写道
eyejava 写道
那我把ss1.0弄来参考一下,drools本身也有这个模块,好像。但是现在上不了他的网站,闷的慌。
springside1.0m3的下载也在sf上,yimlin能帮忙传一份到javaeye的ftp上吗,依赖的是drools 2.5?
springside1.0m3的下载也在sf上,yimlin能帮忙传一份到javaeye的ftp上吗,依赖的是drools 2.5?
我现在没有这块代码,而且依赖2.5!建议还是用3.0毕竟支持dsl。
数据库存储规则是十分必需的,起码可以作规则更改的审计,ss2.0 不做这块是因为drools 3.0自己的road map里有这部分,怕做了无用功,否则anders小明出手作一下估计也不用多少时间:)
这个是可行的,项目中有类似的实现。但是lz的表结构的适用范围相当的窄,只适合一些特殊的规则。
我觉得表结构只需要维护因子的值和关系,担负起drools决策表的作用就足够了。实际的LHS还是手工写,而其中的因子项由数据库维护,RHS这里可以写一个表达式解析器把计算的表达式也由数据库维护。
这样在需求所需要的因子项目不发生变化的情况下可以让客户自己更改表达式,如果只是规则的一些域约束的值发生变化也可以让客户自己修改因子的值。
我觉得表结构只需要维护因子的值和关系,担负起drools决策表的作用就足够了。实际的LHS还是手工写,而其中的因子项由数据库维护,RHS这里可以写一个表达式解析器把计算的表达式也由数据库维护。
这样在需求所需要的因子项目不发生变化的情况下可以让客户自己更改表达式,如果只是规则的一些域约束的值发生变化也可以让客户自己修改因子的值。
youlq 写道
看看这篇文章:
Loading and managing rules dynamically from a database
http://docs.codehaus.org/display/DROOLS/Loading+and+managing+rules+dynamically+from+a+database
Loading and managing rules dynamically from a database
http://docs.codehaus.org/display/DROOLS/Loading+and+managing+rules+dynamically+from+a+database
感觉lz的路子很奇怪,如果说得是这个链接里面的内容那就是我理解的问题,
如果和链接内容的思路相差比较大,还是建议回头想想规则引擎的初衷,整理下思路。
eyejava 写道
找到了springside0.8的代码,ss1.0之后就升级到drools3.0了。
ss0.8中把规则部分的script分成两部分:conditionScript,consequenceScript 来存储,这样做对用户来说还不是得写类似脚本语言的东西吗。
ss0.8中把规则部分的script分成两部分:conditionScript,consequenceScript 来存储,这样做对用户来说还不是得写类似脚本语言的东西吗。
是啊!所以用dsl还是比较好的!
至于在web页面上让用户来点鼠标的,还是要自己完成!
找到了springside0.8的代码,ss1.0之后就升级到drools3.0了。
ss0.8中把规则部分的script分成两部分:conditionScript,consequenceScript 来存储,这样做对用户来说还不是得写类似脚本语言的东西吗。
ss0.8中把规则部分的script分成两部分:conditionScript,consequenceScript 来存储,这样做对用户来说还不是得写类似脚本语言的东西吗。
刚刚竟然打开了sf,并且自动找到一个taiwan的代理,正在下载。
用dsl有什么好处?还不是得手写规则吗,只是变了语法。对于最终用户来说一样是很困难的一件事情,至少在易用性上他会给你打不及格。其他好处是什么?
用dsl有什么好处?还不是得手写规则吗,只是变了语法。对于最终用户来说一样是很困难的一件事情,至少在易用性上他会给你打不及格。其他好处是什么?
eyejava 写道
那我把ss1.0弄来参考一下,drools本身也有这个模块,好像。但是现在上不了他的网站,闷的慌。
springside1.0m3的下载也在sf上,yimlin能帮忙传一份到javaeye的ftp上吗,依赖的是drools 2.5?
springside1.0m3的下载也在sf上,yimlin能帮忙传一份到javaeye的ftp上吗,依赖的是drools 2.5?
我现在没有这块代码,而且依赖2.5!建议还是用3.0毕竟支持dsl。
那我把ss1.0弄来参考一下,drools本身也有这个模块,好像。但是现在上不了他的网站,闷的慌。
springside1.0m3的下载也在sf上,yimlin能帮忙传一份到javaeye的ftp上吗,依赖的是drools 2.5?
springside1.0m3的下载也在sf上,yimlin能帮忙传一份到javaeye的ftp上吗,依赖的是drools 2.5?
eyejava 写道
yimlin 写道
在springside1.0早的时候,就基于drools2.5实现了基于数据库存储的规则,当然现ss2.0用上drools3.0,要把规则放到数据库中也是可以的,不过web界面的编辑就需要自己做了。
我从svn上拿下来的jbossrules包里面 没几个代码,擦亮眼睛找了几圈都没找到,springside那边说正在开发。
现在的版本是没有的!Drools2.5基于数据库版是我今年3月开发的。springside1.0后来也上drools3.0的。
fins 写道
其实我那个规则引擎 不是基于数据库存储
而是基于数据库pl/sql实现的
和java没有关系 功能很弱 所以我也没发到这里来
而是基于数据库pl/sql实现的
和java没有关系 功能很弱 所以我也没发到这里来
你的组织结构让我想起了MS BizTalk的规则组织结构,只不过你最后是通过拼接文本来必要的语法结构。而BizTalk则在表上实现了树形的语法结构。
关于计算因子,也就是Fact,plsql只能怎么做,和java不同的是,通常这些项是数据项,不如java来的丰富。
我个人认为这样的产品或者项目更多是脚本引擎而不是规则引擎,因为规则的推理演算没有重入,而规则的冲突处理在应用程序就消除了。
yimlin 写道
在springside1.0早的时候,就基于drools2.5实现了基于数据库存储的规则,当然现ss2.0用上drools3.0,要把规则放到数据库中也是可以的,不过web界面的编辑就需要自己做了。
我从svn上拿下来的jbossrules包里面 没几个代码,擦亮眼睛找了几圈都没找到,springside那边说正在开发。
在springside1.0早的时候,就基于drools2.5实现了基于数据库存储的规则,当然现ss2.0用上drools3.0,要把规则放到数据库中也是可以的,不过web界面的编辑就需要自己做了。
我这个排他性 和 规则引擎中的排他性定义不同
我这个排他性是这样的
一个规则组内的规则A 规则B 规则C 不是排他的
那么最后会得到类似下面的语句
IF 纪录X 满足 规则A的条件 then 执行 规则A的动作
IF 纪录X 满足 规则B的条件 then 执行 规则B的动作
IF 纪录X 满足 规则C的条件 then 执行 规则C的动作
如果是排他的 那么
IF 纪录X 满足 规则A的条件 then 执行 规则A的动作
ELSE IF 纪录X 满足 规则B的条件 then 执行 规则B的动作
ELSE IF 纪录X 满足 规则C的条件 then 执行 规则C的动作
差别就是 在一个组内 是否满足了自己 就不去判断其他规则了
这个要和规则优先级一起使用
我这个排他性是这样的
一个规则组内的规则A 规则B 规则C 不是排他的
那么最后会得到类似下面的语句
IF 纪录X 满足 规则A的条件 then 执行 规则A的动作
IF 纪录X 满足 规则B的条件 then 执行 规则B的动作
IF 纪录X 满足 规则C的条件 then 执行 规则C的动作
如果是排他的 那么
IF 纪录X 满足 规则A的条件 then 执行 规则A的动作
ELSE IF 纪录X 满足 规则B的条件 then 执行 规则B的动作
ELSE IF 纪录X 满足 规则C的条件 then 执行 规则C的动作
差别就是 在一个组内 是否满足了自己 就不去判断其他规则了
这个要和规则优先级一起使用
fins 写道
可以看看这个
http://www.javaeye.com/topic/41690
http://www.javaeye.com/topic/41690
这个设计很不错。但是你的条件表达式还是一些基于sql的语句啊,如何能让用户也会书写呢?另外你规则组的排他性不知道怎么实现的,对这个我还没有体会到规则交叉带来的麻烦,rete算法可能就是为了解决这个问题的吧。
把不同的计分项目拆解开放在数据库保存发现有很大的问题,因为逻辑运算(与,并,非)无法进行,比如工资>2000 && 性别=女 计分为10分, 这种复杂的组合 很难用数据库来表达,只能写成表达式。
发表评论
该博客是同时发布到论坛的,无法评论在论坛已被锁定的帖子
- 浏览: 394537 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
我的相册
Gmail
共 8 张
共 8 张
最新评论
-
JIRA不完全手册
楼主,发一份完整的资料给我吧 xwj1003@yahoo.com.cn
-- by volking -
java encoding参考
Good ,thanks.
-- by zuowei -
有多少异常可以重来
我今天也遇到这个问题,才搜到这个帖子~ 还没有解决,等恢复哦
-- by javamanlcy007 -
有多少异常可以重来
这个错误解决了,又抱了别的错误~
-- by iceworld4143 -
有多少异常可以重来
解释不太懂,我也遇到这个问题了,可是我没用ant。 :cry: 等回 ...
-- by iceworld4143






评论排行榜