学 习 中 的 思 考
海风
学习计算机知识常常让人陷入无知的恐惧中,过去打破沙堡问到底的精神在这里要有所节制了,我们把握好一个度的问题,要明确自己到底现在最应该知道的是些什么;不执着于现在还不是时候该知道的知识,只于心中存在一个问号待以后有意或无意间来解决。疑问是学习的灵丹妙药,我常常抱着怀疑的精神去思考书本中叙述的知识,亦常常先入为主去推敲未知的知识,但有发现自己的猜测有正确之处便沾沾自喜,如若有误亦为书中的解决之道叹服与兴奋。
MS SQL Server 心得与猜想:
数据库是门高深的学问,有些知识虽然不太清楚,但我们可以推测可以思考。我们知道一个数据库里有很多个表,一个表里有很多字段,一个字段上定义有很多规则。那让我们想想,一个记录里包含所有字段对应的值,而记录的数量是可变的,字段的个数也是可变的,可变加可变让我们创建维护管理数据库带来了方便,问题是,怎样实现这样的功能呢?我们查找数据修改数据时可以选择指定的字段指定的记录,我们也一样用得很高兴,可是,为什么这样子可行呢?在没有看过数据库存储结构有关书籍之前,让我大胆地猜测:字段是相对独立的对象,他拥有自己的属性,我们用数组链表把表中的各个字段链接起来,这样我们就可以动态地增减字段数,各个记录字段的对应值都应该有指向上一个与下一个对应字段值的指针,这样就形成一个十字交叉链表,记录也就可以方便地管理了,我们好像也能自由选择特定的字段来显示与修改了,而且因为有指针这位大侠的帮忙,数据就可以方便地乱放了;可是,还有问题,增减一个字段好像要修改所有的记录,我们的SQL语言好像也是面向集合的语言,这样子的结构可行么,高效么?我不知道,我只是随便想想罢了。还有啊,数据库里表与表之间的关系,在储存结构里又该如何表述呢?缺省与规则又是如何的绑定到字段呢?唉,算了,到此为止,有空再想。
存储过程:存储过程由一组SQL语句组成,他们共同完成一个任务,我们用一个名字(可能还和一些叫参数的符号组成的一串符号)来表示这组语句;那么,在远程访问数据库时,我们就可以向数据库所在的服务器发送这个名字,那么服务器就执行对应的SQL语句组,并返回结果给客务机,这就达到减少发送的数据效果。
触发器:触发器定义了一组SQL语句,当我们对指定的表进行修改时,SQL Server 就会触发对应的触发器,执行特定的SQL语句组,以保证数据的正确性和一致性。
索引:由索引页和数据页组成;索引页由一个或几个数据项为关键字进行排序而组成,同一个关键字可以对应一个以上的记录,并存储有指向特定记录的指针,通过关键字的排序可以加快查找记录的速度,数据页是实际的存储数据的页面。填充因子的作用是:因为在内存与硬盘的数据交换中,总是预先或优先把存储位置相近的数据调入内存以减少缺页中断;所以在每个索引页中预先留出一部分空间,使得系统在新增索引信息时能够保持数据的连续性,从而加快查询速度。
数据库的安全:我们要使用SQL Server,需要使用一个登录名来连接SQL服务器,登录名提供了使用服务器的权力但并没有提供使用服务器中的数据库的权力;用户帐号提供了使用数据库的权力,所以我需要为登录名提供一个用户账号以便在登录服务器的同时能使用其中特定的数据库;不同的用户账号使用数据库的权限是不同的,比如有的用户只能查看数据而不能修改,有的用户能够赋给别的用户使用数据库的权力,于是我们使用角色来为拥有不同权限的用户分类,把拥有相同权限的用用户集中起来管理,我们在创建数据库用户的同时也指定了他在数据中扮演的角色(使用数据库的权限)。系统管理员与数据库拥有者拥有管理数据库的最高权力。我们还可以为数据库用户指定对数据库中的表,视图,函数,存储过程所拥有的权限,以从更低级的数据对象来管理数据库安全。
当我们拥有了使用数据库应有的权限时,在用户应用程序中,我们是怎样使用数据库中的数据的呢?我们可以使用SELECT语句来创建一个临时表,应用程序用户能够看到的使用的仅限于这个临时表,这个临时表拥有指向基表(实际上的有存储数据的表)对应字段数据的指针,通过这个指针,我们就可以间接地修改选定的表中记录记段的数据了。临时表中的指针指向的,可以是基于特定表中特定字段中的数据,拥有如此小对象的数据的地址,我们因此可以联合查询修改数个表中的数据。视图,可以理解为用一个字符串替换一句SELECT语句,以后要使用特定的SELECT时只需使用这字符串替换就行,这样减轻了我们书写SELECT语句的负担,当然也浪费了存储空间来存储(存在系统表中)SELECT语句的信息。因为应用程序用户是通过指针间接访问数据的,所以当我们改变数据库的物理存储结构时,不必修改用户程序,只需修改用户程序中临时表的数据地址就行了,而地址是动态自动分配的,这样就保证的用户程序的稳定性。也许改变物理存储结构,我们只需重新编译一下索引就行了,索引页存有数据的地址,临时表中的地址可方便地从索引页中获取,索引页不大,获取地址的效率很高。
COM的思考;
在C++语言中,类封装了数据和操作其中数据的方法(函数),当我们需要操作类中的数据时,我们就需要调用方法函数,要调用函数操作数据就要知道函数的代码段的地址,在同一进程中,地址可以这样子表示:类名.函数名。无论你身在何处,只要你有办法获取函数的地址,知道函数名的定义,就可以使用函数来操作数据并得到返回结果。于是,当我们有办法联接远程计算机并得到其中可运行程序代码中的一个函数地址,我们就可以远程调用(通过网络传输数据)这个函数使之在计算机中运行并将得到返回的结果传输回本地计算机上。我们要计算机完成的任务,基本上都是通过调用函数来完成的。于是,在我们的程序中,如果我们知道其他可独立编译运行程序中的函数的地址,我们就可以调用他来为我们的程序服务。于是我们就可以把各个相对独立的程序联合起来共同完成我们的任务。COM组件对象模型就是为了解决这个技术问题而设计出来的。在COM中,我们设计了各种类型的接口来为函数调用提供地址,每个接口都拥有自己的函数,也可以有自己私有的数据。各个接口类都有一个派生对象作为COM类的一个成员;于是我们就可通过接口类调用(把派生对象地址赋给接口)存在于COM类中的派生对象的成员函数。那么, COM程序编译独立运行,只要能把派生对象地址赋给接口,再在我们需要使用COM中功能的程序中加入接口,调用COM中的函数功能也就能实现了。COM实现了真正的面向对象技术,他把函数的实现细节完全隐藏了起来,COM组件中,可以方便地新增一个接口来实现新的程序功能,只需在原来的代码加上一个接口代码就行了,原来的接口仍然可用。COM组件类的存储结构是以二进制形式顺序存储的,因此只要知道一个接口的地址就可以通过地址偏移量计算出COM其它接口的地址,也就可以方便地实现接口之间的切换了。我们通过接口调用COM中函数,为了使COM能在不同的语言中使用,专家们设计了标准接口语言IDL,以此为中介,实现用各种语言书写的有相同功能和参数的接口的转换;当我们用特定语言编写COM时,先把其接口定义转换为IDL接口定义的形式,再通过IDL把接口转换为其它语言所能识别的接口;这样就实现了COM代码的重用性与语言无关性。
现在我们遇到的最大问题是:如何创建COM实例并获取其地址供程序使用,如何实现COM代码同时被多个程序所共享。这是个令人头痛的问题,很多地方我都未能理解。为实现COM的共享,我们设计一个所有接口的基类IUnknown接口,IUnknown接口有一个函数QuerInterface来实现接口的切换,一对函数AddRef各Release来增加与减少他的引用计数成员m_dwRef;每当组件返回一个新的接口时,程序就调用AddRef来使m_dwRef加一,当结束一个接口的使用时就调用Release来使m_dwRef减一,当m_dwRef变为0时就删除组件对象。因为其它接口都是从IUnknown派生而来的,他们继承了m_dwRef成员,使这个引用计数能正确记录下正在使用组件的用户数,实现了共享组件的管理。在ATL实现方案中,专家们设计了一个智能指针来封装完成有关引用计数的功能,有人称这种功能的实现者为垃圾收集器。在服务器方面,我们需要做些什么准备呢?我们需要把CLSID、实现文件名等配置信注册到注册表中,以供客户远程激活使用。当客户需要COM服务时,远程计算机根据客户发过来的CLSID在内存中查看对应组件是否已被激活,如果已被激活了,即在组件服务程序中寻找到类对象,再调用其中的方法创建一个对象,并通过QueryInterFace返回一个接口指针给客户使用;如果没被激活,就需要先在注册表中寻找到与CLSID相对应的执行程序地址,在SCM的帮助下装载服务器程序,然后再寻找类对象返回接口指针。
为了解除客户与对象的并发性和重入限制之间的关系的模型,建立对象与进程和线程之间相互关系的模型,出现了套间这个概念。一个套间可被多个对象共享,这些对象共享一组并发性和重入限制,套间被设置为对象接口的一个属性;同一时刻,线程要想使用COM中的方法,必需先进入一个套间中,其它没有进入套间的进程虽然也能得到COM方法的地址,但被禁止调用。套间把客户程序所要使用的COM管理起来,以供客户线程方更安全地调用。唉,其实很多知识我现在还不太明白,不想多说,看了一些书本的描述后,反而让我想起了一些问题。COM是独立编译运行的,里面拥有一些全局变量和在一些方法中需要访问临界资源,如果有多个客户同时需要使用这些变量会发生一些什么情况呢?
很多时候,我的一些想法与思考都只能证明我的无知与肤浅,有实际意义的想法并不是很多,可我已习以为惯,别人喜欢笑就让他笑去吧,反正我现在的确不懂那些知识的,的确很无知。初学COM,有点消化不良,再次把我带到另一个迷惘,我努力发挥智力推测未知,确发现难以找到着力点,推出的结果连自己也觉得荒唐可笑。虽然现在没能对COM有个系统的认知,不过仍然相信自己有能力成为COM专家,因为,我喜欢计算机技术,因为我要靠他吃饭。
2002年7月8日