传言3:存储过程要比 SQL代码更加安全
在执行任何SQL语句之前,数据库引擎都会尝试匹配调用者提供的论证信息和所请求资源的访问权限。根据匹配结果,引擎决定是否执行该SQL代码。
这样看来,从安全角度存储过程显然要比普通的SQL代码更有优势。为什么会这样呢?因为存储过程可看做是数据库中的一个实体,可以由数据库管理员DBA显式给其安全需求,即借助数据库的安全基础设施来保护存储过程,因为存储过程本来就是属于数据库资源的一部分。
而普通的SQL语句就是个字符串,将动态地发送给数据库执行,因此数据库引擎不能将其当成内部资源,也无法把权限关联在它上面。权限仅能应用在SQL将使用的数据表或视图上,这显然属于另一个层次的安全。因此,操作整体上的安全性要交给调用者负责保证。
大多数人应该对上面的分析没有疑义,关键是通过上面的分析可以产生两个相反的结论,且这取决于人们的态度,技能和看待问题的角度。
若你更熟悉数据库,那么通常会停在这里并得出结论:存储过程是设计数据访问层中必不可少的。
不过问问自己这3个问题:存储过程中将要执行哪些类型的操作?这些操作都要带有什么样的签名?在大型系统中你实际需要多少个存储过程?
在我们看来,若你觉得存储过程中必不可少的,那么也会不自觉地在存储过程中实现(至少一部分)业务逻辑,但这一点是我们提倡应该竭力避免的。稍后将继续讨论这个问题,这里我们先来完成对安全性的讨论。
安全性是个横切的关注点,应该在从表现层到数据库的各层中都有处理。今天,基于角色的安全是最灵活且有效的做法。在基于角色的安全模型中,我们对安全性有着双重的保证,第一重是中间层中使用基于角色的安全,第二重是数据库引擎中的声明安全。且这一点和使用动态SQL代码或存储过程并不相关。
若使用存储过程来实现系统的安全性需求,则会不自觉地将数据库开发人员和其它开发人员分离开来。而前面曾提到过,安全性应该是个团队的工作。因些我们就回到了那些倾向于使用存储过程的说法中———“若想保证安全的话,就要使用存储过程”。不过实际上,若你真的想要保证安全,则必须放弃将存储过程作为必不可少的功能的想法。之所以这样说,并不是因为存储过程有什么不好,而是因为若将存储过程作为整个系统的核心,那么必定会让人作出不好的设计决定———从安全角度考虑。你仍然可以使用存储过程,不过不要再说是出于安全性考虑,也不要用存储过程来实现逻辑。那存储过程还有什么用呢?一般也仅用在处理数据表访问上。
传言4:存储过程可以让SQL代码更加稳定且不易改变
软件领域中有很多让人孜孜不倦追求的理想目标,其中一个就是使编程可以不受到数据库模型的变化影响。若某个数据库表发生了变化,会不会影响到其相关的代码吗?这是一个常见的疑虑。不过正确的答案仍然不是使用存储过程。
若将SQL命令放在数据访问层中(就像我们在手工数据访问层中的实现一样),就会在代码和物料数据模型之间建立依赖。若数据模型有所变化,就需要更新代码。不过我们可以说,此类依赖仅仅存在于数据映射器类中,且SQL语句也是作为私有成员声明的。因此虽然存在依赖,不过范围非常小。若数据表发生了变化,必须更新数据映射类。不过这也就是所有需要的修改,仅限于数据访问层内部。
使用存储过程是不是真的能让代码与数据模型的变化完全独立呢?若数据模型发生了变化,那么要实现两种更新:修改SQL代码和修改调用者代码。其实,我们并没有看到在数据映射器类中调用存储过程和普通SQL语句有什么区别。
在我们看来,存储过程可以让数据访问代码更加稳定的说法仅仅是个传言,这个传言是以前的那种系统设计方式的自然产物,即数据库开发人员和其他开发人员基本没有沟通交流。
若你真想完全不依赖于物理数据模型,那么应该选择领域驱动设计,并将数据库设计成一个简单的持久化层。数据访问代码将由O/R映射层负责以参数化查询(甚至是以存储过程)的方式动态生成。
(本文摘自:Microsoft.NET 企业级应用架构设计)Y貧<
来源:
说明:所有来源为 .net学习网的文章均为原创,如有转载,请在转载处标注本页地址,谢谢!
【编辑:Wyf】
打赏
扫码打赏,您说多少就多少