Zhang Jiuan’ Notes

数据库大小表问题

    最近比较忙,因此有时候有些想写文章的想法,但只是在blog里面做了个标记,并没有实际的写出来。今天就要过节了,不防忙里偷闲一下,顺便把这些天的欠债给补上吧:)首先从数据库大小表来补吧。
背景:数据库大小表即一个系统后台数据库的实现有多种。对于有许多属性的一个事物,我们可以使用一张表来表示,当然也可以使用多张表进行分类进行表示。对于是使用一张表进行实现还是使用多张表来进行实现,这对于很多做后台开发的人员来讲是一个争论不体的问题了。下面我们将讨论各自的优缺点。
大表:大表实现有其自身的优点,那就是对于后台服务来讲,IO是一个主要的瓶颈。我们知道,程序和后台数据库交互是需要付出这方面的代价的,那么这就意味着和数据库多交互一次,那么就必须付出相应的IO代价。但对于大表来讲,一次可以将尽可能多的数据一次提取出来,然后对数据做分析整合,这样就可以尽可能少的和后台数据库交互,那么自然它的实现结果是IO代价小。这样系统从性能上来讲是比较好的。但其不是没有缺点,因为尽可能多的数据放在一张表里面,那么必然造成的结果就是逻辑不太清晰,不容易理解,不容易维护,特别是对于不是一对一关系的数据就更难了。
小表:我们从别一个方面看问题,可能就会有另一番景象。我们实现一个系统的时候,我们首先考虑的是系统的部署和结构,很自然下一步想到的这些结构如何由后台数据库来支撑。那么很自然我们会把一系统的某一块的东西使用一张表来支撑,这样逻辑十分清晰;而且从扩展方面,我们可以在这张表内部考虑很多可扩展的点,这是大表很难做到的。因此,这种思想最终的结果也是很明显的,那就是后台会有很多张相应的表,各个子系统会单独有自已的数据库读写和维护。那么这种实现,必然的代价就是数据库读取次数多,IO压力大。
跳出大小表的争论:现在我们想,是否可以跳出大小表的争论点来讨论大小表问题呢?究竟是大表好还是小表好,我们自已的系统的实现究竟是采用大表还是小表呢?笔者认为还是要看应用,需求决定一切。没有不变的技术,只有无限变化的应用。在我们考虑是采用大表还是小表的时候,我们应该考虑它们各自给我们可以带来哪些好处,然后做一些比较和权衡,最终得出自已需要的结论。比如,我们做的系统对象是一家企业,该企业使用此系统来管理内部员工数据,那么现在我们很清楚IO代价不是什么问题,因此甚至我们可以说大表给我们带来的优点是可以乎略的。但是采用小表就不一样了,因为它逻辑清晰,可能之后还会添加不同的考核属性,可扩展性是很重要的。但是如果我们做的应用如果是一个网部的线上服务,比如GOOGLE, BAIDU, SOHU(呵呵,口气大了些)这时必须要考此IO读取代价了,因为每一次请求,我们都需要对其服务,对于第小时千万次服务请求来讲,后台IO的压力也是很繁重的,如果一次请求可以减少一次IO读取的话,那么总的结省代价也是很显而易见的。
    下面以一个具体示例讨论一下大小表:有一家网游公司存在这样一种手机应用,它为线上游戏提供手机验证码服务、声音验证服务。手机可提供多种子服务,手机验证码服务和声音验证是手机服务的一些子服务。每个手机服务又可绑字多个游戏业务,比如游戏充点,造建筑等。现在逻辑结构也就比较清晰了。
对于上面的应用,我们应该怎么来设计和实现呢?思路是多种多样的。
方案一:大表方案。一个用户有唯一的id,因此数据库可以将该用户相关的所有数据存储在一张表里面的一条记录。如下:
t_mobile_service (
F_user_id UNSIGNED INT PRIMARY KEY, /* 用户id*/
F_mobile_service_flag TYNY INT UNSGINED DEFAULT 1, /* 用户是否开能手机服务,只有开能,才可能有子服务 1: 未开通 2:开通 */
F_mobile_token_service_flag TYNY INT UNSIGNED DEFAULT 1, /* 用户是否开通验证验服务 1:未开通 2:开通*/
F_mobile_sound_flag TYNY INT UNSGINED DETAULT 1, /*用户是否开能声音验证功能服务1:未开通 2:开通*/
F_mobile_token_current VARCHAR(32), /*手机当前产生的验证码*/
F_mobile_sound_fingerprint BLOB, /*声音签名*/
F_mobile_token_create_time DATETIME, /*手机验证码产生时间*/
F_mobile_sound_fingerprint_settime DATETIME, /*声音签名设置时间*/
F_mobile_token_bind_service BIG INT UNSIGNED, /*验证码绑定服务*/
F_mobile_sound_bind_servide BIG INT UNSIGNED, /*声音签名绑定的服务*/
F_create_time [...]

接口统一与功能单一

这是今天要补的最后一篇了。这个类似于数据库大小表的问题,同样是一个很长时间以来大家的争论点。在设计的时候,究竟是想着设计一个接口是功能尽可能的单一好呢,它只做一个对应名子的事,最简单的事,这样好呢;还是设计一个接口,它尽可能的通用,可以完成可能的所有的应用好呢?这个争论了很多,但最终还是没有结果。
接口统一:即是接口规范后,所有的可能的该功能的调用,都采用这一种接口调用方式完成。好处自然很明显,那就是使用者不必记一大堆在何处应该调用哪个函数了,一个接口搞定。它有很鲜明的应用实例:printf。我们几乎可以使它打印出各种格式的数据,使用很方便。当然它也存在自身的缺点,那就是函数体实现巨复杂,需要使用一大堆的if语句和一大堆的switch语句来标明所需要的分支,因此很容易出错。
功能单一:功能单一就是一个函数做的事尽可能的简单,这样实现很简洁,基本上就是一个“筒子楼”,可以说想犯错都难:)但是缺点也是显而易见的。它可能会有一些重复代码,另外就是接口巨多,当代码堆到一定量的时候,使用就更加繁锁了。
但这两都是设计需要考量的点,不存在说哪个好哪个劣,主要是你有没有看到哪个好在哪的问题了。
thx
张久安
If you enjoyed this post, make sure you subscribe to my RSS feed!

代码复用、接口复用(C++精髓)

笔者还在学校的时候理解C++最终精髓是两点:代码复用、接口复用。到现在隔的时间挺长了,今天不防把它记录下来,希望不会引起各位高手的嘲笑吧。
C++的特点:封装、继承、和多态。现在我们分别从这些所谓的C++的特点上来讨论它的本质吧。
封装:封装的含意就是对一个空间下的成员变量进行保护,这可能也是class和struct的唯一区别了吧。当然不是说struct不能保护,只是一个默认值而已。但C就没有这些支持吗?答案是肯定的。比如在一个文件的全变量声明成static,那么这个全局变量就是对该文件内部是可见的,对外部是隐藏的。因此从这一点上来看,封装不能算C++特有的东西。只不过是文件和声明的struct内部而已。好,下面对继承再进行分析。
继承:继承就是子类具体父类可继承的方法的属性,那么它本质做了哪些事呢?实际说白了很简单,只是复用了你类的代码,甚至我们可以认为是父类可继承的代码原样照抄一遍。这能算C++特有的吗?C封装的那么多的lib库不同样可以完成这些事吗?因此继承我认为同样不是C++的特性。好了,被人们传颂的C++三大属性在不知觉间被我砍了俩了,可能要被许多C++爱好者猛批一把了。但是下面我还要把第三个所谓的它的特点给否认掉:)
多态:多态是什么呢?即一个抽象事物对于不同的具体事物可以有不同的动作和处理事件,这就是多态。那么多态究竟做了哪些事呢?难道C就没有这样的特性了吗?实际上如果对C有一定深度理解的话,那么如下就不难理解了。声明一个函数指针,放在一个struct内部,在不同时刻对其赋不同的函数指针值,这样就可调用不同函数,这是不是叫多态呢?从本质上讲,这就是所谓的C++的多态,而且也是这么实现的。哈哈,到这儿可以看到神奇的C++竟再也没有可被提及的自已的特点了。
是不是C++真的就没有所谓的特点和特质了呢?答案是当然存在,而且文章题目也很醒目:代码复用、接口复用。现在我们给其抛开那些好听的继承名子,以复用取而代之。复用C库即是,但C++则采用了另外一种复用形式,重要的不是于表象,而在于对事物的抽象理解的复用。如果从这个角度去再解C++的复用,那么你才能真正去理解C++的一点点内涵吧。它可以将宏观世界的物可以很形象的用语言的形式对外再现。把是什么,归属这种性质以符号的形式进行加工进而实现复用。这便是C++的第一个精髓点吧。因此看你对继承这个词的理解程度了,不要人云亦云。
下面再进行接口复用进行更进一步的论述。刚才论讨了C++的继承即是代码复用的特性,下面将说明多态就是接口复用的性质。的确,在C里面使用指针完成可以做所谓C++的所有这些特性。实际C++的胜过C的点并不在于所谓的多态,仍旧在于对编程思想的理解。比如使用C++可以帮助理解这样的事物,同一类动物,对于不同的具体实际,可能做出不同的动作,使用C++可以更加简单形象的描述而已。因此多从更高层次上去理解C++,就可以帮助我们理解具体事物的特性在哪。接口复用即同一个接口,对于不同的使用者可以使用同样的接口调用方式可以得到不同的调用结果,这样方便了代码和系统的统一。
因此,如果读到这儿,所有事情就都很清晰了。所谓的封装、继承、多态要完全抛开了,而应该从另外一个更高的层次去理解它。当你理解到这个层次,C、C++只不过是一个工具,功能没有什么差别。就不再会有C++实现的系统使用C难以实现的困惑了。
笔者愚见。
多谢
张久安
If you enjoyed this post, make sure you subscribe to my RSS feed!

,

返回顶部