楼主: yulihua49

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

[复制链接]
论坛徽章:
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
331#
 楼主| 发表于 2009-4-29 15:12 | 只看该作者
原帖由 newkid 于 2009-4-27 22:55 发表


我知道start_date和on_date不同。问题是:你原来在维护seat_remant表的时候,用的是on_date, 也就是说你并没有根据始发日期汇总的余额。因此现在这个视图的逻辑是完全照搬的,也按on_date来汇总。难道是我程序看错了?

没错,是按on_date汇总的。
这两天又研究了另一个OCI包装器--OCILIB
有点像JDBC。自称速度最快的OCI接口,结果比sqlora慢了两三倍。
里边的函数处理还有错,让我纠正了一个严重错误。

使用道具 举报

回复
论坛徽章:
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
332#
发表于 2009-4-30 04:20 | 只看该作者
原帖由 yulihua49 于 2009-4-29 15:12 发表

没错,是按on_date汇总的。
这两天又研究了另一个OCI包装器--OCILIB
有点像JDBC。自称速度最快的OCI接口,结果比sqlora慢了两三倍。
里边的函数处理还有错,让我纠正了一个严重错误。


那么你#336为什么要按START_DATE查余额?按你原来余额表的设计是不可能查到的,除非你查SEAT表。
不管什么包装器,如果摈弃了SQL的集合操作思想,改用单记录的思维方式,那就不是编程的好工具。

使用道具 举报

回复
论坛徽章:
26
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-01-04 11:49:542013年新春福章
日期:2013-02-25 14:51:24夏利
日期:2013-08-13 23:25:29优秀写手
日期:2013-12-18 09:29:092014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11蓝色妖姬
日期:2015-03-19 09:37:00ITPUB年度最佳技术原创精华奖
日期:2015-03-19 09:43:24
333#
发表于 2009-5-2 10:37 | 只看该作者
原帖由 yulihua49 于 2008-11-18 16:22 发表
现在大家都喜欢Hibernate的啊,要写优雅的数据库持久化啊。
现在,我的C程序员可以只写应用逻辑啦,不必关心SQL,只要知道这20来个函数就行了。

以前那种 应用逻辑的小草淹没在访问逻辑的森林里的情况改善多了。

呵呵,这个帖子好热啊。
我周围很多朋友搞java,都推崇hibernate等ORM的框架;
目的就是自动把数据库的表映射成对象;
然后业务的实现,就通过这些对象进行处理;
说白了,hibernate的作用主要有两个:
1.把对数据库的操作对象化,也就是比直接用存储过程之类更OO;更容易扩展和维护;
2.与数据库无关性,不直接操作数据库,所以数据库可以是msssql,mysql,oracle;而系统不需要做什么改动;

说老实话,我没用过hibernate,而且我基本都是些c/s的系统;开发工具是delphi;
不过,我感觉系统开发,视图+存储工程(包) 就够了;
  在客户端,查询,我从不操作表,基本都是事先写好视图,客户端直接 select * from 视图 where...a=:1 and b=:2 ....;
( 如果在客户端直接操作表,sql太复杂,比如 select a.a1....b.b1 from a,b,c where ... and exists() and... where ....
很容易写错,而且没法用select * ; 很多书上都说,尽量不用select  * ;我却很推重;不仅这样简单,而且动态,客户端不用做映射;
而且经过我测试下来,没觉得select  * 比 select 各个字段效率相差多少;)

  业务点,全部用存储工程(包) ;
   涉及到简单的表的更改操作,用delphi自带的功能完成(也就是让系统自动生成sql提交数据);

没感觉到非要使用ORM之类的东西;

而且,我觉得在项目中,数据库的变动时常用的事情,经常加些字段之类的;
这些在我的系统里,只要简单的修改一下视图,客户端程序不要做任何修改;
但是对于HiberNate这样的框架,就要重新映射,重新生成对象;

当然,对于b/s系统的开发我不熟悉,尝试过几次,开发的繁琐基本让我很难忍受,
举个简单的例子:
     比如要实现 select * from vw1 ; 把数据显示在Grid上;
  在b/s里,要把每个字段通过标签<>一个一个的定义出来 ,而且字段名必须每个不能错;
如果视图vw1发生改变,网页中的各个字段的标签也要一个一个的对应修改,错一个都不行,而且如果错了,只有运行期运行到那里才会发现错误;而且还要指定每个字段的宽度,居左居右,中文意义;各个字段的前后顺序;写的我快崩溃了,虽说这样一路写下来,也不是很复杂,但是这样绑定太“死”了; 以后数据库发生一点点变化,网页里跟者不停的修改代码;就算你用了hibernate这么先进的框架,但是这个工作少不了;我尝试过jquery,extjs,好像都省不了;
  在用户体验上,Grid的数据显示可以说是在以数据库为核心的系统中,是重中之重的环节,如果这个开发太麻烦和僵化,那么我就不知道“敏捷”这这里有何体现;


  而现在在c/s里,由于这么多年下来,可能也是因为积累了些东西,想上面的这个查询;
  我会一句代码也不用写,就能实现:
    1.自动把vw1视图中的各个字段搜索出来,自动生成查询条件;用户可以 实现 select * from vw1 where field1 like(=) :1 ;
    2.在Grid上不需要定义各个字段,动态加载,vw1发生任何变化,都不需要做任何代码的编写;
    而且Grid上能够“记忆”各个字段的宽度,各个字段间的位置顺序,某些字段可以设置成和(平均)统计;各个字段上可以做数据过滤;
   这些不用写一句代码;由于数据库设计的时候,字段名一般不会是中文,鉴于oralce视图的字段可以加备注(mssql没有该功能),所以各个字段的中文显示就是通过视图的备注展现出来的,也不需要写任何一句代码;


再重新回到HiberNate 上;
  1.它的最本质的作用是,是把对数据库的操作变成一个个的对象操作;其做法我觉得有点别扭;数据库是基于二维表的关系型数据库;本身可能不是基于对象的,硬通过一些手段,把它变成所谓的对象,感觉有点牵强附会,也许那一天数据库发生本质变化,本身表结构就是基于对象的,那才能做到真正的OO;现在做这样的“伪OO”,真的给开发提高效率,给维护带来方面吗? 而且这种“伪OO”还要做到数据库无关性,说白了,劈除性能的考虑,对它来说,Access和oracle是没有区别的;说白了,就是把数据库仅做数据存储用,其他的数据库的特性一概屏蔽;
2. oracle的Tom Kittle曾经说过,既然选择了oracle,就要多多的里利用他的特性,否着你为何化那么多钱买这款数据库;
比如oracle的分析函数sum() over() lead/lag, 分组统计rollup,rownum的妙用,connect by 嵌套 ,with 子句嵌套查询 等等;
这些功能放着不用,用所谓的“伪对象”实现,是不是过于复杂了,而且效率也不高。

3.系统的并发,事务,互锁等如何很好的控制,不同的数据库,其并发机制也不一样,我一般把业务写在数据库的package里(mssql好像仅有存储过程),如果并发控制不好,就可以调整存储过程的程序实现;而且客户端我基本不控制事务;需要循环的,就直接把数组作为参数传进来,事务全部在存储过程内部控制,所以客户端很简单;也没有所谓的中间业务层,或者说中间业务层,就是一堆包和存储过程;

4.系统的优化,人非圣贤,孰能无过;谁能保证写的程序是最优化的,一般情况下,如果执行一个操作本来就很快,也就不用考虑优化;
但是随这数据量的增长,业务的复杂;也许某几个关键操作,会运行的很慢;如果用hibernate里的一堆对象,层层嵌套下来,要找到瓶颈,很难;但是如果是存储过程实现,这个发现就简单了,oracle的手段太多了,比如可以用profiler,把过程里的每条sql所消耗的时间展现出来,马上就知道那几条sql需要优化;

5.就算用了HiberNate,可以“简化”开发人员对各种sql技巧的依赖,那么就果真能提高开发效率吗?而且hiberNate还自搞了一个HQL;
我不知道HQL比SQL简化多少,但是有必要简化吗?SQL本身就是面相结果的,已经够简单了,还要如何简化;再说HQL是个通用的功能,那么它就要适应于所有数据库,这样不是弱化各种不同的数据库的特性功能吗?这样做处了实现所谓的通用,却是牺牲了性能和开发效率;


6.所谓通用问题,HiberNate是数据库无关性,能够让开发人员较为方便的更换数据库;但是通用性不仅仅看数据库,万一前台开发工具变了呢,比如一开始用java,后来用.net,php ,ruby ;那不是一样大该程序; 但是如果把业务点都用存储过程实现;那么就算换了前台开发工具,也没有“撼动根基”;也就是说,业务点都用数据库自身实现,就可以弱化对前台工具的依赖;大家都知道,相对来说,数据库的变化较慢,而前台工具却是日新月异;

7.最后说一件关于SQL运行机制的问题,HiberNate说白了,它的所有数据操作不也是自动生成SQL实现的? 而且据说它生的SQL不够优化,有时候很复杂,不容易看懂;我有个疑惑,这种自动生成的SQL你放心吗?一个稍微复杂的操作,它可能是上百个sql实现的;如果用数据库的存储过程实现,客户端只用和数据库交互一次;而HiberNate却是上百次;这样不是既增加了服务端压力,也增加了客户端压力;
还有这些上百个sql对于oracle来说,可是未编译的动态sql,其效率和存储过程相比,可想而知;

我只是说了我的想法,或者说是疑惑,没有贬低HiberNate的意思;我也知道它肯定有它很好的地方,否着为何在java领域那么流行;
我说了这么多,说白了就是希望有人指出我的错误;毕竟做了那么多项目,都是“过分”的依赖于pl/sql了,技术上没有学习新东西;所以思想也一定很落伍;

[ 本帖最后由 qingyun 于 2009-5-2 12:11 编辑 ]

使用道具 举报

回复
论坛徽章:
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
334#
 楼主| 发表于 2009-5-3 17:05 | 只看该作者
原帖由 qingyun 于 2009-5-2 10:37 发表

呵呵,这个帖子好热啊。
我周围很多朋友搞java,都推崇hibernate等ORM的框架;
目的就是自动把数据库的表映射成对象;
然后业务的实现,就通过这些对象进行处理;

欢迎讨论。
你说的在某方面很有道理,无意反驳你,各人有各人的情况。
在数据库-数据库间的数据转换,可以考虑使用存储过程。
在C/S模式下,服务器侧的语言基本确定是C(如果不用C了,DAU也就没用了),客户端语言是可以变化的。而且,ORM或SRM不在客户端发生,客户端只有业务逻辑,没有任何访问逻辑的,也不对任何数据库连接,这是三层C/S 模型的根本优势。
目前,还没发现DAU在速度上有什么劣势,目前还没发现什么地方比存储过程慢。席位发布程序是典型的数据库-数据库程序,如果用存储过程写,很可能有好处,但不是速度方面的,目前它还达不到DAU的速度,DAU是稳定的3000席位/秒。使用C程序,可以自降优先级20级(nice(10);nice(10);),避免发布席位时干扰售票业务(这是现有系统的一大问题),已经经过测试。存储过程的优先级可能难于控制。

前边讲过,OCI的确是ORACLE速度最快的接口,但包装起来就不见得快,比如OCIlib就很慢,而libsqlora8就很快。
我也一直为DAU选择快速的接口系统。

大家对于聚合函数的讨论我同意,DAU支持使用聚合函数,也支持使用ORACLE的任何优势特征,也支持使用存储过程。
大家任何好的建议,我都会加入到未来的系统中。

我与有关项目负责人争论过,他坚持认为DAU无需支持存储过程,我还是坚持把存储过程的支持包括在DAU功能内。
将来也可能产生这样的模型:TUXEDO -> C -> DAU -> 存储过程。

[ 本帖最后由 yulihua49 于 2009-5-3 17:43 编辑 ]

使用道具 举报

回复
论坛徽章:
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
335#
 楼主| 发表于 2009-5-3 17:09 | 只看该作者
原帖由 newkid 于 2009-4-30 04:20 发表


那么你#336为什么要按START_DATE查余额?按你原来余额表的设计是不可能查到的,除非你查SEAT表。
不管什么包装器,如果摈弃了SQL的集合操作思想,改用单记录的思维方式,那就不是编程的好工具。

哇,那是我的错误,已改正,on_date。

使用道具 举报

回复
论坛徽章:
26
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-01-04 11:49:542013年新春福章
日期:2013-02-25 14:51:24夏利
日期:2013-08-13 23:25:29优秀写手
日期:2013-12-18 09:29:092014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11蓝色妖姬
日期:2015-03-19 09:37:00ITPUB年度最佳技术原创精华奖
日期:2015-03-19 09:43:24
336#
发表于 2009-5-4 09:22 | 只看该作者
如果用存储过程写,很可能有好处,但不是速度方面的,目前它还达不到DAU的速度,DAU是稳定的3000席位/秒。使用C程序,可以自降优先级20级(nice(10);nice(10);),避免发布席位时干扰售票业务(这是现有系统的一大问题),已经经过测试。存储过程的优先级可能难于控制。


我刚下载了TUXEDO-Oracle10g,大概80M的样子,还没尝试使用;
dua 不知道是什么,网上好像查不到dua相关的信息,莫非也是也OCI一样的数据驱动;
还是dua是TUXEDO的访问接口?
您说DUA的速度超过存储过程,我有点怀疑(关键两个程序要写的一模一样才能测试出效果);我想擂主newkid 兄可能也不同意这个说法,
不过我可以尝试测试一下,如果真的快很多,
那么可以把频繁调用的对效率要求高存储过程用DUA实现;那确实是一大技术进步?
还有,据说pro*c 效率也高,不过它好像也是oci访问接口,而且配置麻烦,我一直也不会用这个;
pro*c的效率和你的DUA相比,又如何?

当然,由于不熟,我个人现在觉得,在开发和维护上还是存储过程最方便;而且oracle的包也支持了些面向对象功能,虽然没有java那么好;但也在不断完善;

在C/S模式下,服务器侧的语言基本确定是C(如果不用C了,DAU也就没用了),客户端语言是可以变化的。而且,ORM或SRM不在客户端发生,客户端只有业务逻辑,没有任何访问逻辑的,也不对任何数据库连接,这是三层C/S 模型的根本优势。

在C/S模式下,如果有中间层的话,我一般是把它作为数据连接层来处理,也就是客户端不直接反问数据库,而是与中间层交互,中间层有个连接池的处理,中间层负责直接和数据库交互,说白了,中间层就负责邮递员的角色,没有任何逻辑,是一个很轻量级的处理, 业务实现全部在oracle存储过程或包里; 中间层在我眼里的作用就是可以做个连接池;以前没有中间层的时候,客户端我都是都是连接一次断一次,或者定时断(比如30秒断一次),这样保证Session的个数很少;不过因为考虑oracle的Session的通断是一个很“重”的操作,所以才考虑用个中间层处理数据库访问,作用就是调度Session,不要让会话常开常关。所以我这边的三层,大部分工作都在数据层(包含存储过程),中间层很弱(仅是一个数据访问处理),客户端也很弱(就是一些数据查询,存储过程的调用,简单的数据维护等);之所以把大部分工作都放在数据层,目的有两个:1.充分利用oracle数据库的特性;2.方便移植,比如今天用java开发,明天要用c#开发;今天开发c/s,明天开发b/s,无论更换什么前台开发工具,无非在再做一套shell,数据也业务都在数据库自身里实现;
  我这种3层结构处理可能有点“另类”,mvc架构我也不深入研究过,反正是怎么简单怎么来,怎么维护方便怎么来,怎么运行效率高怎么来;

[ 本帖最后由 qingyun 于 2009-5-4 11:19 编辑 ]

使用道具 举报

回复
论坛徽章:
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
337#
 楼主| 发表于 2009-5-4 13:14 | 只看该作者
原帖由 qingyun 于 2009-5-4 09:22 发表

我刚下载了TUXEDO-Oracle10g,大概80M的样子,还没尝试使用;
dua 不知道是什么,网上好像查不到dua相关的信息,莫非也是也OCI一样的数据驱动;
还是dua是TUXEDO的访问接口?
您说DUA的速度超过存储过程,我有点怀疑(关键两个程序要写的一模一样才能测试出效果);我想擂主newkid 兄可能也不同意这个说法,
不过我可以尝试测试一下,如果真的快很多,
那么可以把频繁调用的对效率要求高存储过程用DUA实现;那确实是一大技术进步?
还有,据说pro*c 效率也高,不过它好像也是oci访问接口,而且配置麻烦,我一直也不会用这个;
pro*c的效率和你的DUA相比,又如何?

当然,由于不熟,我个人现在觉得,在开发和维护上还是存储过程最方便;而且oracle的包也支持了些面向对象功能,虽然没有java那么好;但也在不断完善;


在C/S模式下,如果有中间层的话,我一般是把它作为数据连接层来处理,也就是客户端不直接反问数据库,而是与中间层交互,中间层有个连接池的处理,中间层负责直接和数据库交互,说白了,中间层就负责邮递员的角色,没有任何逻辑,是一个很轻量级的处理, 业务实现全部在oracle存储过程或包里; 中间层在我眼里的作用就是可以做个连接池;以前没有中间层的时候,客户端我都是都是连接一次断一次,或者定时断(比如30秒断一次),这样保证Session的个数很少;不过因为考虑oracle的Session的通断是一个很“重”的操作,所以才考虑用个中间层处理数据库访问,作用就是调度Session,不要让会话常开常关。所以我这边的三层,大部分工作都在数据层(包含存储过程),中间层很弱(仅是一个数据访问处理),客户端也很弱(就是一些数据查询,存储过程的调用,简单的数据维护等);之所以把大部分工作都放在数据层,目的有两个:1.充分利用oracle数据库的特性;2.方便移植,比如今天用java开发,明天要用c#开发;今天开发c/s,明天开发b/s,无论更换什么前台开发工具,无非在再做一套shell,数据也业务都在数据库自身里实现;
  我这种3层结构处理可能有点“另类”,mvc架构我也不深入研究过,反正是怎么简单怎么来,怎么维护方便怎么来,怎么运行效率高怎么来;

这么说就是没有发挥中间层的作用。中间层是:1.给数据库层减负,让有限可伸缩的数据库层为更多的客户端提供服务。2.把客户端的一个事务集中成一个调用。
如:申请一组席位,如果有,就返回一组结果。许多逻辑在中间层解决了,减少了网络开销(相对于两层逻辑JDBC+hibernate)。还有安全问题,数据库不对外了,大大提高了安全性。

DAU是我的产品,在这个帖子里发表的征求意见稿,是Data Access Unit的缩写,帮助程序员使用数据库的,类似Hibernate,程序能见到数据,见不到数据库。
使程序简短易写,不易出错,尤其是C语言。它配合TUXEDO最合适,二者优势互补。
比如动态语句的问题,一个业务逻辑,就反复使用那么几个语句,在TUXEDO中,由于是驻留程序,开始的服务编译了这几个语句,今后千千万万的服务都无需编译了,所以,动态语句的缺点在此并不体现,因此DAU不比存储过程慢,原因之一在此。前边有许多测试数据,你可能缺少数值概念,那些数据你用别的数据库,别的工具是很难超越的。
也就是newkid的程序可以跟我有一拼(比我慢不到两倍不算了啊,就算相等,机器环境有所不同),程序糙点的,慢个十几倍很平常。又不是打导弹,差1毫秒死定了。

运算程序,C语言比PL/SQL快得多,这是毋庸置疑的,尤其是在where子句的索引列上进行函数运算,你就彻底完蛋了。前边有个时间金字塔,TUXEDO层的任何CPU开销都是并行的(多核、多机、多进程),其中只有很少的数据库访问时间开销才需要数据库服务器承担。这样数据库服务器就有很多时间为其他服务器服务。要让TUXEDO承担尽可能多的任务(这层是无限可伸缩的),在巨大系统中这样设计才能保证高度突发的峰值访问(如春运抢票)。

关于无关性,存储过程具有前端开发语言的无关性,而JDBC,Hibernate、DAU具有数据库无关性。
需要哪种无关性,是每个项目的不同需求。我们是不一定哪种数据库(现在只是看好ORACLE,DB2呢也说不定。有了DAU,应用可以先写着,等数据库选定了,改写DAU即可),中间件一定是TUXDO,C语言。所以就这样了。

[ 本帖最后由 yulihua49 于 2009-5-4 15:02 编辑 ]

使用道具 举报

回复
论坛徽章:
26
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB十周年纪念徽章
日期:2011-11-01 16:20:282012新春纪念徽章
日期:2012-01-04 11:49:542013年新春福章
日期:2013-02-25 14:51:24夏利
日期:2013-08-13 23:25:29优秀写手
日期:2013-12-18 09:29:092014年新春福章
日期:2014-02-18 16:41:11马上有车
日期:2014-02-18 16:41:11蓝色妖姬
日期:2015-03-19 09:37:00ITPUB年度最佳技术原创精华奖
日期:2015-03-19 09:43:24
338#
发表于 2009-5-4 16:27 | 只看该作者
这么说就是没有发挥中间层的作用。中间层是:1.给数据库层减负,让有限可伸缩的数据库层为更多的客户端提供服务。2.把客户端的一个事务集中成一个调用。



1.中间层给数据库层减负,我不太能理解,虽说C这样的语言效率更高,比如在执行数学运算,循环等方面是优于pl/sql,但是对于一个信息系统,大部分的业务操作都是针对表的添加删除修改 ;pl/sql的数据更新我想速度应该是最快的,而复杂的运算并不是很多,很少用到背包递归这类的算法;再者,我不清楚你的中间层是否想pro*c那样带预编译的,如果你的中间层本质也是通过一条条的动态sql于数据库交互,那效率低的去了;也许你这个是带编译的,就算带编译,那么这个编译的东西也是应该放在数据库层才是; 还有就是如果你的程序逻辑某些地方不够优化,怎么去跟踪查找也不会想pl/sql那么轻松;

2.

如:申请一组席位,如果有,就返回一组结果。许多逻辑在中间层解决了,减少了网络开销(相对于两层逻辑JDBC+hibernate)。还有安全问题,数据库不对外了,大大提高了安全性。。


申请一组席位类似买火车票,这些票号是不是本身就有,还是动态生成,如果是后者,我觉得有个问题,就是并发难控制,
比如有100个人同时10张火车票(100个终端同时操作),这个锁的机制难处理;

我的思路是这样的:
  假如某列火车共有1万张票,其数据表事先就有:
  票号       是否已售
   001        已售
   002        已售
   003        未售
。。。。。。。。。



我写一个简单的买票的存储过程:

create procedure 买票(p_数量)
as
TYPE T_票号 IS TABLE OF varchar2(10) INDEX BY BINARY_INTEGER;
v_票号 T_票号;

begin
       update 票 A set A.是否已售=' 已售'
       where A.票号 in (select C.票号 from (select B.票号 from 票 B where B.是否已售=' 未售'  order by  B.票号) C
                                where rownum<=p_数量)
       returning A.票号 BULK COLLECT into  v_票号 ;
   
      if v_票号.Count<p_数量
    then
          rollback;
         dbms_output.put_line(‘要买'||p_数量||'张票,但只剩下||v_票号.Count||’张了');
          return;
      end if;

       for i in  v_票号.first ..v_票号.Last
       loop
              dbms_output.put_line( v_票号(i) );
      end id;
end;


其实核心离不开数据库的查询和更新,这个有个技术难道,就是并发的控制:
   1.你不能每次查询的时候把表都锁起来,这样只能串行执行;也就就算100个人同时买票,但实际上还是相当于一个个排队来的;
   2.如果不锁表,那么查询的结果就不是准确的,那样就没法正确的给票号打上已售标志;
所以,通过oracle特有的功能,一句话搞定,既有更新也有查询,不会有并发异常,也不用人为锁表;

如果这个功能通过一个与数据库无关的东西(或者说任何数据库都通用的东西)实现,那么我觉得挺难的。或者说有风险或者低效。

[ 本帖最后由 qingyun 于 2009-5-4 16:48 编辑 ]

使用道具 举报

回复
论坛徽章:
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
339#
 楼主| 发表于 2009-5-5 11:27 | 只看该作者
原帖由 qingyun 于 2009-5-4 16:27 发表



1.中间层给数据库层减负,我不太能理解,虽说C这样的语言效率更高,比如在执行数学运算,循环等方面是优于pl/sql,但是对于一个信息系统,大部分的业务操作都是针对表的添加删除修改 ;pl/sql的数据更新我想速度应该是最快的,而复杂的运算并不是很多,很少用到背包递归这类的算法;再者,我不清楚你的中间层是否想pro*c那样带预编译的,如果你的中间层本质也是通过一条条的动态sql于数据库交互,那效率低的去了;也许你这个是带编译的,就算带编译,那么这个编译的东西也是应该放在数据库层才是; 还有就是如果你的程序逻辑某些地方不够优化,怎么去跟踪查找也不会想pl/sql那么轻松;

2.



申请一组席位类似买火车票,这些票号是不是本身就有,还是动态生成,如果是后者,我觉得有个问题,就是并发难控制,
比如有100个人同时10张火车票(100个终端同时操作),这个锁的机制难处理;

我的思路是这样的:
  假如某列火车共有1万张票,其数据表事先就有:
  票号       是否已售
   001        已售
   002        已售
   003        未售
。。。。。。。。。



我写一个简单的买票的存储过程:

create procedure 买票(p_数量)
as
TYPE T_票号 IS TABLE OF varchar2(10) INDEX BY BINARY_INTEGER;
v_票号 T_票号;

begin
       update 票 A set A.是否已售=' 已售'
       where A.票号 in (select C.票号 from (select B.票号 from 票 B where B.是否已售=' 未售'  order by  B.票号) C
                                where rownum

售票逻辑本帖前边有,请花点时间看看,我跟newkid讨论许久。


席位是上边席位发布程序根据母表发行的。
申请席位要首先‘占用’,交易完成时再‘购买’,此逻辑适用于所有对号入座系统。

置完‘占用’状态,瞬间就解锁了。

关于中间层分担数据库开销:
这页302楼有一个时间金字塔模型:
http://www.itpub.net/viewthread. ... ;extra=&page=31
这是我们分析系统吞吐量的模型,其中RAC就是ORACLE的数据库服务器。
在TUXEDO层里只有部分时间是需要RAC服务的。,TUXEDO层可以有许多的机器、CPU、核、进程。这一层的时间开销可以通过增加资源来解决。
在申请席位之前,会有一个查询车次、到发站的操作,边查数据库边计算运行周期。也可以完全在存储过程做。但上万台客户端要在3-4台RAC服务器做,压力太大。
因此我们还是逐个记录提取到TUXDO服务层,在这里计算、组合数据。其中只有10%左右的时间需要访问RAC。大部分时间十几台TUXEDO服务器的数百进程并行作业。
RAC只为它们提供数据,如果大量数据重复请求,还可以在各层实现缓冲,实际数据存取量是很小的,所以总体速度和吞吐量要比存储过程快很多。

关于调试,DAU是按照过程逻辑操作的。
其实我们已经习惯按过程逻辑实现用户的业务需求。
在关键步骤上写日志是主要的调试方法。
DAU的日志系统可以按售票窗口记载数据,包括语句。bind变量和值,执行状态吗,结果数据等。本帖前边也发表了日志内容供参考。
反正我感觉分析问题比存储过程方便多了。newkid的那个程序我到现在都没读懂,更不要说分析了。现在把那个程序交给别人读,看是否能读懂。
我前边的xwfb程序已经被很多人读过了,都能读懂,还被改写成TPF程序,都是孩子们自己干的,我没干涉。

[ 本帖最后由 yulihua49 于 2009-5-5 13:50 编辑 ]

使用道具 举报

回复
论坛徽章:
0
340#
发表于 2009-5-20 16:23 | 只看该作者
study

使用道具 举报

回复

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

本版积分规则 发表回复

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