楼主: yulihua49

[讨论] 侃一下关于程序的“柔性”

[复制链接]
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
211#
 楼主| 发表于 2025-9-16 10:01 | 只看该作者
本帖最后由 yulihua49 于 2025-9-16 11:24 编辑
newkid 发表于 2025-9-16 03:03
我的回忆在慢慢苏醒,你说的这个“复杂计算”,莫非就是你津津乐道的那个清算程序?就是根据一张票的出入口 ...

这个项目投产了,只不过原定的清分没有采用,数据一直用于与旧系统的对比。但是区段客流和车次客流还是按这个数据统计,因为没有其他办法可以代替,没有办法每趟车派人去数吧?我也无权对算法说三道四,甚至发现算法的缺陷进行反映和建议,也被告知这不归你管,你就管实现。这就是国企的官僚性,没办法。现实就是如此,不评论,只需要实现。
算法的巨大计算量,没有任何项目经理敢于将它交给存储过程,你就看用了3台32核服务器,就可以想象它的计算量。就算你用PLSQL可以计算一个数据(实际这也不可能),你如何调动3台32核的RAC数据库引擎共同完成大批量处理?如何把数十万的数据分配给这96个线程,不重不漏均衡分配?再者,ORACLE的售价,是与处理能力相关的,这个规模的系统,售价得几百万了吧?不算硬件投资,已经超过本项目投资了。我们是在旧有的数据库平台(2节点RAC,这个平台还承担其它很多任务),配微机服务器去完成这个任务,那时候这种32核的服务器非常的便宜,所以,采用了把数据从数据库提取出来,分发给多台服务器的多个线程并行处理,再把计算结果存回数据库的架构设计。
这里就是用这个例子谈一下柔性编程,如何在数据结构变更时,能够减少程序的改动。类似197,198楼的例子的程序,在系统里多着呢,数据结构的修改也是经历无数次了,如果不是柔性编程,每次数据修改都要经历长时间的全面测试,谁知道哪个角洛被遗忘了呢。这个系统一直运行着呢,已经十几年了,北京地铁已经增加到近20条线路600多个车站了,而且增加了刷手机进站刷指纹进站等等,增加不少数据表,也会增加不少列。系统没有任何问题呀,足见这个方案的可靠性,可维护性。



使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
212#
 楼主| 发表于 2025-9-16 10:56 | 只看该作者
newkid 发表于 2025-9-15 21:45
有多复杂?用上GPU了吗?很多时候人们都把数据库当作存储设备,不知道它还是计算设备。所谓“搞不定”往往 ...

不是图像矩阵算法,所以暂时,没有用GPU,从今天的角度看,用AI也许是解决困境的方法,应该是后人的任务吧。
前边说了,投资问题,使用旧有的数据库系统,它承担着大量的其他任务,把他的资源全部占有不合适吧?
再说ORACLE软件价格是按照处理能力定的,拿它用作计算资源成本太高了呀!国企不能像小公司那样拿个免费版无限使用!还有责任问题,使用盗版或超出授权产生的商业纠纷谁也无法承担责任。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
213#
 楼主| 发表于 2025-9-16 11:12 | 只看该作者
本帖最后由 yulihua49 于 2025-9-16 21:59 编辑
newkid 发表于 2025-9-15 21:45
有多复杂?用上GPU了吗?很多时候人们都把数据库当作存储设备,不知道它还是计算设备。所谓“搞不定”往往 ...

这样说吧,这个算法在我来之前就已经开发试验了,那时候没用数据库,全用文件,单线程。
测试数据是1天的业务量,400万条数据,计算了11小时。公司领导对计算结果满意,但是算的太慢了。所以找到了我,介绍了这个项目和算法以及当前进度。我很感兴趣,而且一直在玩并行计算,很有把握为算法提速,就来到了这个公司,解决这个问题,2011年底过来,2013年4月试投产,纳入运行系统。
当时提出了3个方案,我的算一个,还有一个就是用外部表把网传数据加入数据库,测试后速度太慢,光是入库时间就超出了要求,还没计算呢,这个方案他自己就否了(就一个线程入库,怎抵得上我15个连接并发入库!)。我的架构,从接收数据,计算入库,在测试环境需要半小时到40分钟,基本算达到要求。然后才购买设备,计划是3台8核,采购时发现32核的价格已经低于计划价,就这样了。
新系统开通,拿到新系统调试优化后的测试,就那个400万的数据,150秒全部完成。性能稳定,反复测试,都是这个数据。
198楼是反刍时用的,真正150秒计算入库的是这个程序:

一次1000条。

static int insert_DAO(OAD *oadp,char *stmt)
{
int beg;
int cc,ret,n;
T_SQL_Connect *SQL_Connect=oadp->SQL_Connect;
DAU *dau;
int recnum=oadp->max_rows_of_batch;

        dau=OAD_get_DAU(oadp);

        beg=
        ret=n=0;
        ret=OAD_exec(oadp,beg,recnum);//OAD已经被初始化成insert
        if(ret>0) n+=ret;
        if(ret == recnum) {
                trans_commit(SQL_Connect);
                return n;//如果没有异常,这活儿就算干完了,比merge省事太多了吧!你们谁有兴趣写一个150列的merge?就如199楼的。
        }
        trans_rollback(SQL_Connect);
//出错,从新按单条插入,并找出错误记录
CUT_PI_EXIT_stu *recp=(CUT_PI_EXIT_stu *)oadp->recs;
        n=0;
        for(beg=0;beg<recnum;recp++,beg++) {
                DAU_init(dau,NULL,NULL,recp,NULL);
                *stmt=0;
                dau->srm.hint="/*+RULE*/";
                ret=DAU_insert(dau,stmt);
                if(!ret) {
                        n++;
                        continue;
                }
                if(dau->SQL_Connect->Errno == 3114) {
                        return -3114;
                }
                net_pack(stmt,recp,CUT_PI_EXIT_tpl);//没有这个柔性程序,把这个150列的数据序列化,得多费劲!改数据结构这个小破地方也别落下!
                ShowLog(1,"%s:insert %s[%d]:%s error=%d,%s",__FUNCTION__,dau->srm.tabname,  //出错的数据写入日志
                        beg,stmt,oadp->SQL_Connect->Errno,oadp->SQL_Connect->ErrMsg);
        }
        trans_commit(SQL_Connect);
        return n;
}

上面的程序是这样调用的,绑定一个数组:
                OAD_init(&s_OAD,NULL,sdp->data,sdp->num);//次级初始化,绑定数据
                saved_num=insert_DAO(&s_OAD,stmt);//插入数据库
                sdp->saved_num=saved_num;
这个程序依然是柔性的,数据结构的变化不需要修改。

介绍下反刍:收到原始的进出站信息(UD,User Data)时进行计算入库,就是那个insert_DAO();
但是,通常运行图还没到(运行图通常每4小时收一次,UD随时来),大部分数据实际上没有经过计算就入库了,被标记为未计算。
当运行图数据到达后,管理器就会吧所有未计算的数据提取出来,分包,分配给多个服务器的多个线程进行计算,update入库。这个过程就被戏称为反刍,后来竟然成为项目术语。
198楼的程序就是反刍的一部分,所描述的流程就是反刍的流程。

使用道具 举报

回复
论坛徽章:
94
生肖徽章2007版:牛
日期:2012-08-02 22:43:00紫蛋头
日期:2012-12-08 09:43:38鲜花蛋
日期:2012-11-17 12:02:07鲜花蛋
日期:2013-02-05 21:53:34复活蛋
日期:2012-11-17 12:02:07SQL极客
日期:2013-12-09 14:13:35SQL数据库编程大师
日期:2013-12-06 13:59:43SQL大赛参与纪念
日期:2013-12-06 14:10:50ITPUB季度 技术新星
日期:2012-11-27 10:16:10最佳人气徽章
日期:2013-03-19 17:24:25
214#
发表于 2025-9-16 11:38 | 只看该作者
yulihua49 发表于 2025-9-15 17:40
谢谢你的批评。我在努力学习,所以跟这里的大佬进行沟通。也请你看看206楼,提点意见。另外,我的数据库包 ...

咱们不都退休了么,还学啥,而且这东西其实也没啥值得深究的。横竖已经成为不了计算机科学家了,还不如去研究哈耶克

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
215#
 楼主| 发表于 2025-9-16 11:48 | 只看该作者
本帖最后由 yulihua49 于 2025-9-16 11:53 编辑
udfrog 发表于 2025-9-16 11:38
咱们不都退休了么,还学啥,而且这东西其实也没啥值得深究的。横竖已经成为不了计算机科学家了,还不如去 ...

玩具。觉得还能给人一些启发。哈耶克也看。原来有保密协议,离职5年内不能披露公司技术。现在超过5年了,那些程序可以拿出来讨论了。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
216#
 楼主| 发表于 2025-9-16 12:53 | 只看该作者
本帖最后由 yulihua49 于 2025-9-16 20:25 编辑
newkid 发表于 2025-9-15 08:51
我还以为你的源数据放在文件里呢?现在才看到“管理器从数据库读出数据”,数据已经在库里面,再写外部表不 ...

能支持表连接,聚合吗?
支持。多表模板需要手工制作,也有半自动的工具,就是手工写meta,建立模板和结构体。


以下就是从表结构生成模板的程序片段,就使用了多表模板:


/* Formatted on 2011/09/29 */
static T_PkgType TAB_COLUMNS_tpl[]={   //生成模板用的模板
        {CH_CHAR,49,"c.TABLE_NAME Fld_Tlb_Name",0,-1},
        {CH_CHAR,49,"c.COLUMN_NAME  Fld_Column_Name"},
        {CH_CHAR,31,"c.DATA_TYPE Fld_Column_Type"},
        {CH_SHORT,sizeof(short),"DATA_LENGTH Fld_Column_Len"},
        {CH_SHORT,sizeof(short),"DATA_PRECISION"},
        {CH_SHORT,sizeof(short),"c.DATA_SCALE Data_Scale"},
        {CH_SHORT,sizeof(short),"k.POSITION Fld_PK"},
        {-1,0,"ALL_TAB_COLUMNS c, "                                //表名表达式
              "(SELECT C2.TABLE_NAME,C2.COLUMN_NAME,C2.POSITION "
              "FROM USER_CONSTRAINTS C1,USER_CONS_COLUMNS C2 "
              "WHERE C1.OWNER = :Fld_Column_Name AND "   //可以使用绑定变量
              "C1.TABLE_NAME=:Fld_Tlb_Name AND C1.CONSTRAINT_TYPE='P' AND "
              "C2.CONSTRAINT_NAME=C1.CONSTRAINT_NAME) k ",0}
};

/* auto make pattern */



static int descDAO(DAU *DP,char *stmt)
{
int ret;

// 如果是其它数据库,要改。
        strcpy(stmt,"WHERE c.TABLE_NAME = k.TABLE_NAME(+) "
                 "AND c.COLUMN_NAME = k.COLUMN_NAME(+) "
                 "AND c.OWNER = :Fld_Column_Name AND c.TABLE_NAME=:Fld_Tlb_Name "
                 "ORDER BY c.TABLE_NAME, c.COLUMN_ID ");
//        DP->srm.hint="/*+client_result_cache*/";
        ret=DAU_select(DP,stmt,0);
。。。。。。。
        if(!srmp->tabname || !*srmp->tabname) return -1;
        DAU_init(&patt_DAU,SQL_Connect,0, &tab_col,TAB_COLUMNS_tpl);
        n=descDAO(&patt_DAU,stmt);

。。。。。。

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
217#
发表于 2025-9-16 22:06 | 只看该作者
本帖最后由 newkid 于 2025-9-16 23:44 编辑
yulihua49 发表于 2025-9-16 10:01
这个项目投产了,只不过原定的清分没有采用,数据一直用于与旧系统的对比。但是区段客流和车次客流还是按这 ...

谁说"没有其他办法可以代替"? 我不是说了用配置表就可以吗?现在算法完全不可人工校验,而且它也只是猜测,猜错猜对全由自己说了算。我的方法是可以验证的。用我说的方法完全不需要额外的硬件配置,不需要任何额外开销,就让数据库做对的事!
你们的方法有个高大上的名字叫做鲁布哥德堡算法:
https://www.acfun.cn/v/ac27574073

使用道具 举报

回复
论坛徽章:
520
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
218#
发表于 2025-9-16 22:08 | 只看该作者
yulihua49 发表于 2025-9-16 11:48
玩具。觉得还能给人一些启发。哈耶克也看。原来有保密协议,离职5年内不能披露公司技术。现在超过5年了,那 ...

我195楼提了一个问题,你们单位去O了吗?
另外,你的老帖子找回来了,恭喜!
itpub.net/thread-1088197-1-1.html

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
219#
 楼主| 发表于 2025-9-17 12:11 | 只看该作者
newkid 发表于 2025-9-16 22:08
我195楼提了一个问题,你们单位去O了吗?另外,你的老帖子找回来了,恭喜!itpub.net/thread-1088197-1-1.h ...

我问过这个问题。都要求去O,但是暂时旧系统不改。
如果去O,这个包装器也可以派上用场,他想用啥数据库,就给他做啥接口。
前边提过,ORACLE改DB2的故事。
当前。ORACLE依然是**的关系数据库,我担心他们去O后系统会有很大的问题。
我也做好准备,跟AI学习了各种数据库的访问方法。
很遗憾在退休前没有搞定ODBC驱动,不过DB2的CLI是类ODBC的。

使用道具 举报

回复
论坛徽章:
14
2009新春纪念徽章
日期:2009-01-04 14:52:28沸羊羊
日期:2015-03-04 14:51:52优秀写手
日期:2014-03-14 06:00:13马上有房
日期:2014-02-18 16:42:022014年新春福章
日期:2014-02-18 16:42:022013年新春福章
日期:2013-02-25 14:51:24ITPUB 11周年纪念徽章
日期:2012-10-09 18:08:15蜘蛛蛋
日期:2012-06-27 21:08:142012新春纪念徽章
日期:2012-01-04 11:53:29ITPUB十周年纪念徽章
日期:2011-11-01 16:23:26
220#
 楼主| 发表于 2025-9-17 12:12 | 只看该作者
本帖最后由 yulihua49 于 2025-9-17 12:21 编辑
newkid 发表于 2025-9-16 22:08
我195楼提了一个问题,你们单位去O了吗?另外,你的老帖子找回来了,恭喜!itpub.net/thread-1088197-1-1.h ...

非常感谢。那个帖子太长了,没办法备份,有什么好办法备份吗?我自己都很惊讶,这个技术竟然是2008年做的,我的印象好像是2009~2010.老了脑子不好使了。
在这里聊柔性这个话题,实际的对象应该是C/C++程序员在访问数据库的应用系统设计的,这种人太少了,在C++坛子里,几乎没有人感兴趣数据库访问。
用数据库的,多半是JAVA人员。他们有hibernate,不感兴趣这个话题。那个hibernate,虽然可以ORM,但是不能做到柔性编程。

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表