一、数据库安全性
1.创建用户
CREATE USER user_name IDENTIFIED BY password
[DEFAULT TABLESPACE def_tablespace]
[TEMPORARY TABLESPACE temp_tablespace];
2.修改用户密码
ALTER USER user_name IDENTIFIED BY new_pwd;
PASSWORD用来修改当前登录用户的密码;
3.删除用户
DROP USER user_name;
4.系统特权
系统特权允许用户在数据库中执行特定的操作。
向用户授予系统特权
GRANT sys_privilege TO user_name [WITH ADMIN OPTION];
WITH ADMIN OPTION选项使该用户能将该系统特权授予其他用户;
PUBLIC是一个表示所有用户的关键字,向PUBLIC赋权,即相关于向所有用户赋权。
检查用户的系统特权:查询数据字典 user_sys_privs
撤销用户的系统特权
REVOKE sys_privilege FROM user_name;
系统特权不会出现级联撤销的情况。
5.对象特权
对象特权允许用户对数据库对象执行特定的操作。
向用户授予对象特权
GRANT obj_privilege ON obj_name TO user_name [WITH GRANT OPTION];
WITH GRANT OPTION选项使该用户能将该对象特权再授予其他用户;
查询已授予的对象特权:
通过查询user_tab_privs_made可以检查某个用户对哪些表向其他用户开放了哪些对象特权;
通过查询user_col_privs_made可以检查某个用户对哪些列对象开放了哪些特权;
查询已接受的对象特权
通过查询user_tab_privs_recd可以检查某个用户被授予了哪些表上的哪些对象特权;
通过查询user_col_privs_recd可以检查某个用户被授予了哪些列的对象特权;
同名对象的创建
CREATE PUBLIC SYNONYM synonym FOR obj_name;
撤销用户对象特权
REVOKE obj_privilege ON obj_name FROM user_name;
对象特权会被级联撤销。
6.角色
角色是一组特权,它可以分配给一个用户或其他角色。
创建角色
CREATE ROLE role_name [IDENTIFIED by role_pwd];
为角色授权
GRANT obj_privs ON obj_name TO role_name;
GRANT sys_privs TO role_name [WITH ADMIN OPTION];
GRANT role_name,..... TO role_name;
将角色授予用户
GRANT role_name TO user_name [WITH ADMIN OPTION];
检查授予用户的角色
通过查询user_role_privs可以检查已经授予一个用户哪些角色。
检查授予角色的系统特权
通过查询role_sys_privs可以检查已经授予一个角色哪些系统特权。
检查授予角色的对象特权
通过查询role_tab_privs可以检查已经授予一个角色哪些对象特权。
默认角色:
一旦为某个用户授予了一个角色,就会自动将这个角色配置为默认角色。即为该用户授予的所有角色都被视为该用户的默认角色,除非用ALTER USER或EM等进行指定。
ALTER USER user_name DEFAULT ROLE role_name,....|ALL [EXCEPT role,....] |NONE;
启用或禁用角色
SET ROLE ALL [EXCEPT role_name,...|NONE| role_name [IDENTIFIED BY pwd];
撤销角色
REVOKE role_name FROM user_name;
删除角色
DROP ROLE role_name;
二、创建表、序列、索引和视图
1.创建表
CREATE [GLOBAL TEMPORARY] TABLE table_name(
column_name type,....
) [ON COMMIT {DELETE|PRESERVE} ROWS];
[GLOBAL TEMPORARY]说明创建的是临时表;
ON COMMIT DELETE表示行在事务的末尾被删除,即该临时表是事务型的,默认为事务型;
ON COMMIT PRESERVE表示行在会话的末尾被删除,即该临时表是会话型的。
通过查询user_tables可以获得有关表的信息;
通过查询user_tab_columns可以获得有关表中各列的信息;
通过DESC[RIBE]命令可以查询表的结构;
2.创建序列
CREATE SEQUENCE
sequence_name --序列名称
[START WITH start_num] --起步数,默认为1
[INCREMENT BY increment_num] --递增量,默认为1,必须小于maxvalue_num-minvalue
[{MAXVALUE maxvalue_num | NOMAXVALUE}]--指定最大序列值,必须大于等于start_num且大于minvalue,默认为NOMAXVALUE
[{MINVALUE minvalue_num | NOMINVALUE}]--指定最小序列值,必须小于等于start_num且小于maxvalue,默认为NOMINVALUE
[{CYCLE|NOCYCLE}]--达到最大值或最小值后是否继续循环取序列值,默认是NOCYCLE
[{CACHE cache_num|NOCACHE}]--指定在内存中保存的个数,默认为20个,NOCACHE表示不缓存
[{ORDER | NOORDER}];是否确保按照请求次序生成,默认为NOORDER。
通过查询user_sequences查询序列的信息
sequence_name.currval:序列当前值
sequence_name.nextval:序列下一个值
修改序列的语法格式与创建序列差不多,使用ALTER SEQUENCE sequence命令。但不能个性序列的初值,修改后的最小值不能大于当前值,最大值不能小于当前值;
DROP SEQUENCE sequence_name删除序列对象。
3.创建索引
通过查询user_indexes获得索引的有关信息。
通过查询user_ind_columns获得列索引的信息。
4.创建视图
通过user_views查询视图的有关信息。
通过user_constraints查询有关约束的相关信息。
5.通过查询user_procedures视图可以获得有关过程、函数和包的信息。
三、数据库对象
1.创建对象类型
CREATE [OR REPLACE] TYPE obj_type_name AS OBJECT(
member_name member_type,...
MEMBER FUNCTION fun_name RETURN return_type,...
MEMBER PROCEDURE proc_name ,.....
)[NOT FINAL | FINAL |NOT INSTANTIABLE];
NOT FINAL表示该对象类型在定义另一类型时被继承,默认为FINAL;
NOT INSTANTIABLE表示该类型不能创建对象实例。
继承的表示:
CREATE [OR REPLACE] TYPE obj_type_name UNDER obj_type_name_exists(
member_name member_type,....
MEMBER FUNCTION fun_name RETURN return_type,...
MEMBER PROCEDURE proc_name ,.....
);
obj_type_name_exists称为超类,obj_type_name称为子类型。
包含方法或函数的对象类型,必须创建对象体。
创建对象体的方法与创建包体的方法相似:
CREATE [OR REPLACE] TYPE BODY obj_type_name AS
.....
END;
对象类型可以用来定义表中的列,这种列称为列对象,同时对象类型也可以包含嵌入对象类型;
也可以用对象类型定义整个表,这种表称为对象表。
CREATE TABLE table_name OF obj_type;
2.对象引用和对象标志符
对象表可以使用对象引用为对象表间的关系建立模型而不是外键。对象引用使用REF类型进行定义,通常都用作指向对象表中对象的指针。对象表中的每个对象都具有惟一的对象标志符(OID),它可以存储在REF列中。
eg.
CREATE TABLE purchases(
id NUMBER PRIMARY_KEY,
customer REF person_typ SCOPE IS object_customers,
product REF product_typ SCOPE IS object_products
);
SCOPE IS子句将对象引用限制在特定表中的对象上。上例中,customer列被限制在指向object_customers对象表中的对象;product列被限制在指向object_products对象表中的对象.
可以使用内置的VALUE()函数从对象表中查询记录,这种方法把记录看作真正的对象,并在对象类型的构造函数中返回对象的属性。VALUE()函数接受表别名为参数;
3.对对象表进行DML操作
通过使用对象表名.列对象名.对象类型来引用对象表中列对象的对象类型值;
通过列对象类型(对象类型值,...)(称为构造函数)来为某列对象赋值,也可以忽略构造函数,直接赋值;
注意对REF列的赋值方式:
eg.
INSERT INTO purchases(id,customer,product)
VALUES
(1,
(SELECT REF(oc) FROM object_customers oc WHERE oc.id=1),
(SELECT REF(op) FROM object_products op WHERE op.id=1)
);
可使用DEREF()函数通过REF列的值访问它所指几的对象表中的记录;该函数接受REF列作为参数。
eg.DEREF(customer):将REF列customer内的记录显示出来;(不用此方法,显示出来的将是该记录的对象标志符)
4.自定义构造函数
在定义对象类型时,可以自定义构造函数。
CONSTRUCTOR FUNCTION fun_nane(property1 property_type,...) RETURN SELF AS RESULT;
自定义构造函数的实际代码包含在对象体中。
CREATE [OR REPLACE] TYPE BODY obj_type_name AS
CONSTRUCTOR FUNCTION fun_nane(property1 property_type,...) RETURN SELF AS RESULT IS
BEGIN
SELF.property1 := ...;--初使化语句
RETURN;
END;
END;
四、集合
1.变长数组
用来存储一个有序元素集合,每个元素有一个索引,该索引对应元素在数组中的位置,变长数据存在大小限制,但可以动态更改;
CREATE TYPE type_name AS VARRAY(n) OF data_type(m);
eg.
CREATE TYPE varray_address_type AS VARRAY(2) OF VARCHAR2(50 CHAR);
创建名为varray_address_type的变长数组类型,可以存储最多2个VARCHAR(50 CHAR)字符串;
变长数据类型也是一种自定义的数据类型,可以用来定义表列;
通过查询user_varrays视图获得变长数组的信息。
填充变长数组元素的方式也是通过构造函数来设定。
变长数组元素的更新只能通过整体更新的方式即如果想要改变变长数组的一个元素,必须提供数组的所有元素。
2.嵌套表
任意数量元素的一个有序集合,所有元素是同一数据类型的。嵌套表有单个列,该列的类型可以是内置的数据库类型,也可以是对象类型。如果嵌套表的列类型是对象类型,则表可以被看作一个多列表,对象的每个属性是一列。可以插入,更改和删除嵌套表的单个元素。
创建嵌套表类型:
CREATE TYPE nest_table_type_name AS TABLE OF data_type;
eg.
CREATE TYPE nested_table_address_typ AS TABLE OF array_address_type;
注意:不要指定嵌套表的最大大小,因为可以在嵌套表中插入任意数目的元素。
使用嵌套表类型定义表列
CREATE TABLE table_name(
.....
) NESTED TABLE column_name1 STORE AS nest_table_name ;
NESTED TABLE子句标识了嵌套表列的名称,STORE AS指定了实际嵌套表的名称。可以独立于包含嵌套表的父表访问嵌套表。
可以通过查询user_nested_tables视图中获得嵌套表的信息。
填充嵌套表元素也是通过类型构造函数来进行的。
嵌套表元素可以单独更新,可以插入,更新和删除嵌套表元素。通过TABLE子句和一个查询嵌套表的子查询可以完成这样的操作。
eg.
INSERT INTO TABLE
(
SELECT column_name1 FROM table_name WHERE conditition
)
VALUES (
定义嵌套表类型的数据类型的构造方法
);
UPDATE TABLE
(
SELECT column_name1 FROM table_name WHERE conditition
) alias
SET .....
WHERE ....
;
DELETE FROM TABLE
(
SELECT column_name1 FROM table_name WHERE conditition
) alias
WHERE conditition;
3.集合方法
COUNT:返回集合的元素数目;
DELETE:删除集合中的所有元素
DELETE(n):删除第n个元素
DELETE(n,m):删除从第n个到第m个元素
EXTEND:添加一个元素,设置为空值
EXTEND(n):添加n个元素,设置为空值
EXTEND(n,m):添加n个元素,设置为m
FIRST:返回集合的第一个(最小的)索引号。如果集合为空,则返回空值
LAST:返回集合的最后一个(最大的)索引号。如果集合为空,则返回空值
NEXT(N):返回n后面的元素的索引号。如果n后面没有元素,则返回空值
PRIOR(N):返回n前面的元素的索引号。如果n前面没有元素,则返回空值
TRIM:删除末尾一个元素
TRIM(n):删除末尾n个元素
大对象
LOB由LOB定位器和LOB内容两部分组成。如果LOB内容大于4KB则存储在表内;
BFILE只有定位器存储在数据库中,定位器指向包含LOB内容的外部文件。这些外部文件可以通过计算机的文件系统访问。BFILE列可以指向位于任何媒体上的文件。
使用CLOB和BLOB
1.初始化CLOB和BLOB。
在向CLOB和BLOB中写入内容之前,必须首先初始化LOB列。通过调用一个生成并返回定位器值的函数完成这一操作。
EMPTY_CLOB();
EMPTY_BLOB();
2.通过UPDATE语句向BLOB或CLOB列插入数据;
使用BFILE
1.创建目录对象
在BFILE列中存储文件指针之前,必须首先在数据库中创建一个目录对象,它表示文件在文件系统中的存储目录
CREATE OR REPLACE DIRECTORY dir_name AS 'dir_path_';
2.用文件指针填充BFILE列
使用BFILENAME(dir_name,file_name)函数。
优化技术:
1.执行连接时使用完全限定的列引用,即对于连接表中的字段,在引用时加上表名或表别名进行完全限定;
2.尽量使用CASE表达式来代替多个查询;
3.建立表索引来优化查询。索引的候选列应该用于存储范围广泛的值;好的索引候选列应该是对于每个记录包含惟一数字的列,差的索引候选列是只包含小范围数字代码的列。在使用分级查询时(CONNECT BY)应该为START WITH和CONNECT BY子句所引用的列添加索引;
4.尽量使用WHERE代替HAVING;
5.尽量使用UNION ALL,而不是UNION ALL;
6.使用EXISTS而不是IN;
7.使用EXISTS而不是DISTINCT;
8.尽量使用绑定变量;
执行计划:
1.创建计划表:/ORACLE_HOME/rdbms/admin目录下的utlxplan.sql;
2.生成执行计划:EXPLAIN PLAN SET STATEMENT_ID=statement_id FOR sql_statement;
statement_id:赋给执行计划的名称;
sql_statement:SQL语句;
3.查询计划表:
SELECT id ||
DECODE(id,0,'',LPAD(' ',2*(level-1))) || ' ' ||
operation || ' ' ||
options || ' ' ||
object_name || ' ' ||
object_type || ' ' ||
DECODE(cost,NULL,'','Cost=' || position) AS execution_plan
FROM plan_table
CONNECT BY PRIOR id = parent_id
AND statement_id =v_statement_id
START WITH id =0
AND statement_id = v_statement_id;
查看执行计划的顺序是:由内向外,由上而下。
收集表统计信息
ANALYZE TABLE table_name COMPUTE STATISTICS;
收集完统计信息之后,则使用于基于成本的优化;