楼主: yulihua49

[PRO*C] 看我做的数据库包装器

[复制链接]
论坛徽章:
0
371#
发表于 2009-7-3 15:22 | 只看该作者
原帖由 qingyun 于 2009-7-3 09:03 发表


不用存储过程,也是通过SQL来访问数据库,大部分开销都是在数据查询或存储上;
我怎么也搞不明白,用存储过程或通过其他手段操作数据库有什么本质区别;
我个人认为的本质区别是:
   存储过程可以一个复杂的业务通过封装成成百上千条SQL一次性提交给服务器执行后返回结果;
   而其他手段,比如中间件之类, 执行一个复杂的业务,就是只不过把这些成百上千条SQL封装一下(比如HiberNate,本质也是SQL);一条一条的在数据库服务器和中间服务器之间而回传递;数据库服务器和中间服务器都是上千次的来回传递加大了彼此的消耗;何来的资源节约,效率提高,CPU的负载平衡(可能也只是中间层的平衡而已);

这就好比领导分配一件事情:
   存储过程的做法,就是接受命令后,自己埋头去一步一步的做;做好了后把结果告诉领导;
   而所谓的中间件做法就是,领导下达一个命令后,员工做一步要提交文档告诉领导,领导看好后再下达下一个指示,以此往复多次,最终完成这件事情;
  第一种做法,没有大量的中间反馈;效率高,领导很轻松,员工也不累;
  第二种做法,大量无谓的中间过程;领导和员工都很累;
  而且如果这件事以后有了改进做法,也是第一种做法方便改进;

你说的是二层C/S模式,而我们是三层的,有一个中间的应用服务层,也是把成百上千的SQL语句完成后,一次向客户端返回结果。
它的执行时间现在看来和存储过程差不多。
从测试结果来看,newkid的程序的确cpu开销非常小,但这是一个高手的杰作,我周围没有一个人能写出这样的程序。它几乎没有运算,完全是数据转移。
要是我们的人,用存储过程按过程思路来写,就写成跟C程序一样的东西,那肯定要比C程序性能低得多。

[ 本帖最后由 yulihua49_cu 于 2009-7-3 15:26 编辑 ]

使用道具 举报

回复
论坛徽章:
0
372#
发表于 2009-7-3 15:31 | 只看该作者
原帖由 newkid 于 2009-7-3 00:47 发表
闹了半天你是不是在说我的存储过程?我的写法运行起来到底效果怎么样?
你这种规模的应用,把所有计算逻辑放到数据库去也不会增加多少负载。一个应用服务器足矣,再多也是浪费。

现在的测试都是DEMO,真正的业务要比这复杂多了,负载也要大多了。
这个测试只是表示出各个部分的时间比例用于估算未来的系统。
虽然测试中,你的程序表现出较大的优势(CPU消耗非常小),但是我们不可能大范围采用你的办法。
1.这是库对库的程序。将来库对客户端的程序是主流形态。
2.我们没有能力写出很多很多如此高超的程序。
我们要让即使是傻瓜,写出可靠而快速的程序。

你的程序,有点毛病或想改改,基本都要晕死(功力不够,容易走火入魔)。

[ 本帖最后由 yulihua49_cu 于 2009-7-3 15:47 编辑 ]

使用道具 举报

回复
论坛徽章:
0
373#
发表于 2009-7-3 15:39 | 只看该作者
原帖由 〇〇 于 2009-7-3 10:43 发表

一位网友的签名
优选语言顺序
sql plsql java c 放弃,tom也是这么说的

同意。问题是,C淘汰不掉,那就要搞出使用它的方便的办法。
那些不得不用C的人,还在POR*C、OCI、ODBC的泥潭中苦苦挣扎。
要么,用存储过程,好好跟newkid学,要么用DAU,两条路回头是岸。

[ 本帖最后由 yulihua49_cu 于 2009-7-3 15:44 编辑 ]

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
374#
发表于 2009-7-3 15:53 | 只看该作者
原帖由 yulihua49_cu 于 2009-7-3 15:31 发表

现在的测试都是DEMO,真正的业务要比这复杂多了,负载也要大多了。
这个测试只是表示出各个部分的时间比例用于估算未来的系统。
虽然测试中,你的程序表现出较大的优势(CPU消耗非常小),但是我们不可能大范围采用你的办法。
1.这是库对库的程序。将来库对客户端的程序是主流形态。
2.我们没有能力写出很多很多如此高超的程序。
我们要让即使是傻瓜,写出可靠而快速的程序。

你的程序,有点毛病或想改改,基本都要晕死(功力不够,容易走火入魔)。

即使是傻瓜,非常不容易写出可靠而快速的程序。

使用道具 举报

回复
论坛徽章:
0
375#
发表于 2009-7-3 16:06 | 只看该作者
原帖由 〇〇 于 2009-7-3 15:53 发表

即使不是傻瓜,非常不容易写出可靠而快速的程序。

为什么不试试DAU呢?有了它,我们不少的新手都写出了快速而可靠的程序。
都用在TUXEDO的应用服务器上,都是面对大批客户端的关键而频繁使用的功能。
它不仅提供了可靠而高效的数据库访问工具,而且提供了字符串处理,加解密、日志系统、配置系统,SOCKET工具。。。。
整个系统设计的着眼点就是解决C语言烦人的内存违例问题。提供的工具都具备完善的违例检查。
比如数据打包程序DAU_dispack(),你给的字符串超长怎么办?我会自动截断。绝不会让程序飞了。

可能有人写过TUXEDO程序,飞掉或内存泄漏很烦人的(运行一段时间就完蛋了),据此说C程序(尤其是应用程序)应该淘汰,不冤。
而我们的DAU的C程序,TUXEDO服务如此坚固可靠,不管运行多长时间,始终可靠,内存占用始终不变。
我们用了太长篇幅讨论DAU的速度。而较少提及它的可靠性。

速度?我跟newkid的PK,你们看见了。不信,你们用jdbc、hibernate,jAVAbean,试试?
你才会知道什么叫C的速度。

[ 本帖最后由 yulihua49_cu 于 2009-7-3 16:34 编辑 ]

使用道具 举报

回复
论坛徽章:
0
376#
发表于 2009-7-3 16:46 | 只看该作者
原帖由 〇〇 于 2009-7-3 10:41 发表
5分钟内如何插入40万条以上的数据?
用sqlldr

再show一个专用加载程序,把另一个系统的车站表加载到我们的车站表,二者内容格式不完全相同,你怎么用sqlldr加载,而且是增量加载。
每秒5000个,150万/5分钟:

  1. #include <stdio.h>
  2. #include <kpapp.h>
  3. #include <libgen.h>


  4. T_PkgType  T_sta_tpl[]={
  5.     {CH_CHAR,4,"station_code",0,-1},
  6.     {CH_CHAR,11,"station_name"},
  7.     {CH_INT,sizeof(int),"statis_code"},
  8.     {CH_CHAR,4,"spell"},
  9.     {CH_CHAR,4,"sta_code"},
  10.     {CH_CHAR,2,"JM"},
  11.     {CH_DATE,9,"beg_date","YYYYMMDD"},
  12.     {CH_DATE,9,"end_date","YYYYMMDD"},
  13.     {-1,0,0,0}
  14. };

  15. typedef struct {
  16.     char station_code[4];
  17.     char station_name[11];
  18.     int statis_code;
  19.     char spell[4];
  20.     char sta_code[4];
  21.     char JM[2];
  22.     char beg_date[9];
  23.     char end_date[9];
  24. } T_sta_stu;

  25. int loadfile(T_SQL_Connect *SQL_Connect,char *buf,int buflen)
  26. {
  27. char *p,tabn[512];
  28. DAU _DAU;
  29. int rows,ret;
  30. int upd,loss;
  31. char *tabname;
  32. int num;
  33. FILE *ifd;
  34. SRM srm;
  35. STATION_stu station;
  36. T_sta_stu sta;

  37.     ifd=fopen("DF02.bcp","r");  //车站表   
  38.     if(!ifd) {
  39.         perror("DF02.bcp");
  40.         return -1;
  41.     }
  42. ShowLog(5,"loadfile:entry,DF02.bcp opened");
  43.     num=0;
  44.     upd=loss=0;
  45.     SRM_init(&srm,0,&sta,T_sta_tpl);
  46.     DAU_init(&_DAU,SQL_Connect,0,&station,STATION_tpl);
  47.     data_init(&station,STATION_tpl);
  48.     for(rows=0;!ferror(ifd);rows++) {
  49.         fgets(buf,buflen,ifd);
  50.         if(feof(ifd)) break;
  51.         TRIM(buf);
  52.         if(!*buf) {
  53.             rows--;
  54.             continue;
  55.         }
  56.         if(!(++num %10000)) {
  57.             trans_commit(SQL_Connect);
  58.             ShowLog(5,"loadfile:num=%d,rows=%d",num,rows);
  59.         }
  60.         SRM_pkg_dispack(&srm,buf,'\t');
  61.         strlower(sta.spell);
  62.         SRM_copy(&_DAU.srm,&srm,"station_code,station_name,spell,statis_code");
  63.         station.beg_date=rstrfmttojul(sta.beg_date,"YYYYMMDD");
  64.         station.end_date=rstrfmttojul(sta.end_date,"YYYYMMDD");
  65.         ret=DAU_insert(&_DAU,buf);
  66.         if(ret) {
  67.             if(SQL_Connect->Errno==DUPKEY) {
  68.                 *buf=0;
  69.                 ret=update_by_PK(&_DAU,buf);
  70.                 if(ret==1) upd++;
  71.                 else {
  72.                     ShowLog(1,"update err=%d,%s",
  73.                         SQL_Connect->Errno,
  74.                         SQL_Connect->ErrMsg
  75.                     );
  76.                     loss++;
  77.                 }
  78.             } else {
  79.                 ShowLog(1,"insert:err=%d,%s,buf=%s",
  80.                     SQL_Connect->Errno,
  81.                     SQL_Connect->ErrMsg,
  82.                     buf);
  83.                 loss++;
  84.             }
  85.             rows--;
  86.         }
  87.     }
  88.     trans_commit(SQL_Connect);
  89.     DAU_free(&_DAU);
  90.     fclose(ifd);
  91.     ShowLog(2,"loadfile:rows=%d,upd=%d,loss=%d",rows,upd,loss);
  92.     return rows;
  93. }


复制代码


注意这几句:
//人家的数据加载到人家的结构里
      SRM_pkg_dispack(&srm,buf,'\t');
//spell字段变小写
        strlower(sta.spell);
//把人家的结构的某些字段拷贝到我的结构
        SRM_copy(&_DAU.srm,&srm,"station_code,station_name,spell,statis_code");
//修改几个字段的格式
        station.beg_date=rstrfmttojul(sta.beg_date,"YYYYMMDD");
        station.end_date=rstrfmttojul(sta.end_date,"YYYYMMDD");
//我的数据插入数据库
        ret=DAU_insert(&_DAU,buf);
如果你一个一个字段的处理,不仅繁琐,还非常容易飞掉,因为二者的数据根本就是不同的,我用了不同的模板约束之。
这几句所有函数都是DAU系统提供的,它保证了程序又快又可靠。基本半傻的程序员都很容易写出这程序(事先要读读DAU手册)。
在专用加载程序里,被特别处理的列是点了列名的。但在存取这些表时仍然不点列名。
模板写了一次,用了好多次。还可以在别的程序中反复使用。


这程序,没用一丁点怪异语句,都是最简单最基本的C语言。

[ 本帖最后由 yulihua49_cu 于 2009-7-3 17:15 编辑 ]

使用道具 举报

回复
论坛徽章:
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
377#
发表于 2009-7-4 01:24 | 只看该作者
你说的是二层C/S模式,而我们是三层的,有一个中间的应用服务层,也是把成百上千的SQL语句完成后,一次向客户端返回结果。
它的执行时间现在看来和存储过程差不多。

你这个中间的应用服务器,就是数据库的客户端,对数据库而言,和C/S模式并无区别。你的做法是把本来一个SQL可以做的事拆成“成百上千”的小SQL, 给数据库造成了额外负担;如果存储过程仅仅是照搬你这套做法(比如把JOIN写成嵌套游标),那当然是差不多。但我们提倡的是尽量写出高效的SQL, 把存储过程仅仅当作是一个轻量级的包装器。


从测试结果来看,newkid的程序的确cpu开销非常小,但这是一个高手的杰作,我周围没有一个人能写出这样的程序。

不知道是在夸我还是损我?我那个存储过程完全没有高深的技巧,就是普通的表连接、子查询,任何学过一阵子SQL的程序员都能写出来。
比较有挑战的是从你那一团乱麻似的代码中把需求解读出来,这是一个庞大的逆向工程,确实需要一定功力。

要是我们的人,用存储过程按过程思路来写,就写成跟C程序一样的东西,那肯定要比C程序性能低得多。

如上所述,思路是要变的,存储过程也必须使用高效的SQL才能发挥数据库的威力。


现在的测试都是DEMO,真正的业务要比这复杂多了,负载也要大多了。

我再次向你发出挑战,随便你提什么复杂需求,你甚至可以把需求修改到你认为对自己最有利的状态。老是跟风车大战没什么意思。

虽然测试中,你的程序表现出较大的优势(CPU消耗非常小),但是我们不可能大范围采用你的办法。
1.这是库对库的程序。将来库对客户端的程序是主流形态。

我不是也写了一个售票的过程吗?
任何的事务处理都可用存储过程;你在事务中和数据库打交道次数越多,存储过程越能体现优势。

2.我们没有能力写出很多很多如此高超的程序。
我们要让即使是傻瓜,写出可靠而快速的程序。

如果我是你们公司的程序员,看到这里肯定是百感交集。
虽然ORACLE的CBO对SQL做了很多自动优化的工作,但我并没有感觉自己是傻瓜,还是能享受到动脑筋的乐趣。

整个系统设计的着眼点就是解决C语言烦人的内存违例问题。提供的工具都具备完善的违例检查。
比如数据打包程序DAU_dispack(),你给的字符串超长怎么办?我会自动截断。绝不会让程序飞了。

要我说你这“自动截断”的做法是错误的。
你怎么能保证自己截断的是无关紧要的数据?你不声不响把数据砍了,这是对用户不负责。
正确的做法是报错,回滚事务。

速度?我跟newkid的PK,你们看见了。不信,你们用jdbc、hibernate,jAVAbean,试试?

你还是在讲那个批量数据加载?拜托你下次记得在后面COPY&PASTE这么一段:
我的包装器加载数据很快……比PLSQL还快……但是! 用外部表+MERGE(或INSERT SELECT或其他SQL)还更快!

你就从“但是”后面开始拷贝,省得每次我都要跟在你后面贴。

再show一个专用加载程序,把另一个系统的车站表加载到我们的车站表,二者内容格式不完全相同,你怎么用sqlldr加载,而且是增量加载。


谁说格式要相同才能用SQLLDR? 你去好好看一下SQLLDR的使用文档。人家的控制文件那才叫强大。
增量加载:先加载到临时表,再执行SQL.
这个例子也可用外部表,连加载过程都可省略。

使用道具 举报

回复
论坛徽章:
407
紫蛋头
日期:2012-05-21 10:19:41迷宫蛋
日期:2012-06-06 16:02:49奥运会纪念徽章:足球
日期:2012-06-29 15:30:06奥运会纪念徽章:排球
日期:2012-07-10 21:24:24鲜花蛋
日期:2012-07-16 15:24:59奥运会纪念徽章:拳击
日期:2012-08-07 10:54:50奥运会纪念徽章:羽毛球
日期:2012-08-21 15:55:33奥运会纪念徽章:蹦床
日期:2012-08-21 21:09:51奥运会纪念徽章:篮球
日期:2012-08-24 10:29:11奥运会纪念徽章:体操
日期:2012-09-07 16:40:00
378#
发表于 2009-7-4 08:48 | 只看该作者

回复 #384 yulihua49_cu 的帖子

请yulihua49对下面的问题提出建议
http://www.itpub.net/thread-1177956-1-1.html

使用道具 举报

回复
论坛徽章:
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
379#
发表于 2009-7-4 09:19 | 只看该作者
替他回答你:上TUXEDO服务器,用余氏包装器!
FENNG的文章很有意思,等会过去说两句。

使用道具 举报

回复
论坛徽章:
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
380#
 楼主| 发表于 2009-7-4 18:36 | 只看该作者
原帖由 〇〇 于 2009-7-4 08:48 发表
请yulihua49对下面的问题提出建议
http://www.itpub.net/thread-1177956-1-1.html

好像是偏向OLAP的东西,用户数又不是很多,什么技术都差不多,看你的队伍适合什么。关键是发挥数据库的优势。

好像里边有人质疑开游标,开游标怎么了?我提高效率的主要办法就是开游标,保持游标,面向游标的操作完全摈弃了语法分析问题。

我用游标保持技术PK掉了LDAP。openldap号称具有极快的读取速度。结果使用DAU,ORACLE性能高于LDAP。

[ 本帖最后由 yulihua49 于 2009-7-4 19:28 编辑 ]

使用道具 举报

回复

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

本版积分规则 发表回复

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