MILY: PMingLiU">原著作者:defectcomputing.com">Jim Czuprynski
大纲
对ORACLE数据库对象的改动,使得应用程序中用到的数据对象在某段时间内处于无效状态,从而带来致命的错误。本文讨论些技术,可供DBA在实际应用中竟可能地降低数据库改动和应用程序间的冲突。
正如古时的一位著名哲学家说的那样“唯一不变的就是变化”。DBA的职责就是要控制数据库的变动,使之有序。依赖于你的IT团队的稳定性和你们开发和支持应用的稳定性,你们可以从容应付每天甚至于每时每刻地呼叫,需要变动数据库结构。
自从我负责为客户的数据库系统提供24(小时)×7(天)的支持以后,其中一个工作就是我非常关注让我们的应用能够提供持续的稳定的性能而不需要特定的数据库维护。而且,我发现只要事先规划周密,我可以建立一个安全层来让应用和它们要访问的数据库对象是绝缘的。
安全层
使用基本的视图来隔离应用
就其形式来看,一个基本的视图只不过是一个view引用了表中的所有列。当创建了一个新的表后,我一般会马上创建一个基本视图和为这个视图创建一个公共同义词(public synonym),然后,把必要的对象访问权限授权给适当的角色。
既然oracle允许用DML语句直接操作基本表,那我可以把DML重定位到基本视图上从而替代基本表。下面就是一个例子在HR DEMO的模式下,有一个EMPLOYEES的表,我授予了角色OLTPROLE完全访问视图的权利。
CREATE OR REPLACE VIEW hr.bv_employees AS
SELECT * FROM hr.employees
/
CREATE PUBLIC SYNONYM employees FOR hr.bv_employees;
GRANT SELECT, INSERT, UPDATE, DELETE ON hr.bv_employees TO OLTPROLE;
使用基本视图的最大好处就是我可以把精力集中在应用的读写数据上,与此同时也把应用同破坏性的DROP TABLE和TRUNCATE语句隔离。同时,我也防止了那些“低级DBA”和“过分热心的开发者”在匆忙或意外地删除了重要的数据库对象。
忠告:注意如果往基本表了添加了新的列,基本视图中是不会自动添加这个列的,除非重新把编译基本视图。这是把双刃剑,当你达到了隔离应用与数据库对象的变动,但同时也不能立即得到新增加的列。而且,要记住,字段上的约束是不包括在基本视图中的(例如:列有一个NOT NULL的约束而且没有提供缺省值,或者有一个CHECK约束),发出的INSERT语句会失败。
使用基本视图隔离应用访问指定的数据
既然可以为视图的列指定别名,我们可以利用这个特性来限制用户返回的数据。我们还是使用EMPLOYEES这个表,我想限制OLTPUSER角色只能访问必需的列,换句话说,在插入一条雇员信息的时候只需要填写那些非空的必需列。
DROP VIEW hr.bv_employees;
CREATE OR REPLACE VIEW hr.bv_employees (
empid,
fname,
lname,
email,
hire_date,
job_id)
AS
SELECT
employee_id,
first_name,
last_name,
email,
hire_date,
job_id
FROM hr.employees
/
DROP PUBLIC SYNONYM employees;
CREATE PUBLIC SYNONYM employees FOR bv_employees;
GRANT SELECT, INSERT, UPDATE, DELETE on hr.bv_employees TO oltprole;
现在我以OLTPUSER用户对基本视图bv_employee执行DML语句,增加记录的时候只需要必要的信息。
INSERT INTO employees
VALUES (501, 'Damien', 'McGillicudy', 'damienm@oracle.com', TO_DATE('12/31/1999'), 'FI_ACCOUNT');
COMMIT;
SQL> SELECT *
2 FROM employees
3 WHERE empid >= 500
4 ORDER BY empid;
EMPID FNAME LNAME
---------- -------------------- -------------------------
EMAIL HIRE_DATE JOB_ID
------------------------- ------------------- ----------
501 Damien McGillicudy
damienm@oracle.com 12/31/1999 00:00:00 FI_ACCOUNT
未完待续