1 索引
index,也称目录。数据库会在具有唯一性的列上自动添加唯一性索引。
-
创建索引:
create index 索引名 on 表名(字段名); -
删除索引:
drop index 索引名; -
修改索引只能修改索引的名字,若修改其它,只能删除这个索引后重新创建。
-
如何查看表中的索引:
select table_name,index_name,uniqueness,status from user_indexes where table_name = ‘表名(大写)’; -
索引类型:
- 普通索引:normal
create index 索引名 on 表名(字段名); - 唯一性索引:unique(在添加前字段中一定不能有重复的值)
create unique index 索引名 on 表名(字段名); - 位图(分类)索引:bitmap (用于在数据量比较大,数据可选范围比较小的字段,比如:性别,每个人都有,但是数据可选的范围很小)
create bitmap index 索引名 on 表名(字段名); - 函数索引:在一个列上通过函数计算后得到的结果上创建索引(一般也属于普通索引)
create index 索引名 on 表名(函数名(字段名));
- 普通索引:normal
-
创建索引的优缺点:
- 能够更快的定位到查询数据,有效提高查询效率
- 但增删改数据的时候,数据库会浪费资源去维护索引
-
所以一般加在何处?
- 数据量比较少不需要加索引
- 数据量比较多,查询比较多,增删改比较少的列适合添加索引
2 存储过程
procedure,相当于新华字典的目录。在服务器端,能够被一个或者多个程序调用的SQL语句集。
-
创建存储过程:
create [or replace] procedure 过程名(参数名 in 参数类型,参数名 out 参数类型) as 变量名 变量类型 := 值; begin SQL语句集; end;
or replace的意思是若已存在这个过程名,则替换覆盖掉这个过程。
-
存储过程的参数列表
- 参数名后面的in表示参数列表中这个参数为传入参数,out表示参数列表中这个参数为传出参数。
- 存储过程可以没有参数,如果没有参数则过程名之后不能出现括号。当然也可传入多个传入参数,多个传出参数。
- 存储过程没有返回值,而是通过传出参数来返回数据。
-
例:实现一个名为pro_hi的存储过程,参数中,若传入参数是1,则返回你好;若传入参数是2,则返回再见。
create or replace procedure pro_hi(dzh in number,bb out varchar) as begin if dzh = 1 then bb := '你好'; else if dzh = 2 then bb := '再见'; end if; end if; end; /
-
调用存储过程
declare 变量 数据类型 := 初始值; begin 过程名(参数,变量); end;
运行存储过程,首先需要开启输出行:
set serveroutput on;
put_line()将必要的信息输出,以便对存储过程进行调试,只有将serveroutput变量设为on后,信息才能显示在屏幕上。
-
运行上面的例子:
declare val varchar2(20) := ''; begin pro_hi(1,val); dbms_output.put_line(val); pro_hi(2,val); dbms_output.put_line(val); end; /
3 触发器
trigger,创建时默认创建表级触发器。常用于调用序列实现主键自增、实现对表操作记录生成日志表等。
for each row:行级触发器
-
创建触发器:
create or replace trigger 触发器名 before/after insert/update/delete on 表名 --什么时候的什么操作时执行触发器 for each row --默认表级触发器,加这一行代表这是一个行级触发器 begin SQL语句集; end;
例1:Oracle通过触发器调用序列实现主键自增
1.创建表
create table test(
id int primary key,
name varchar2(20)
);
2.创建序列
create sequence seq_test;
3.创建触发器
create or replace trigger tri_insert_test
before insert on test
for each row
begin
select seq_test.nextval
into:new.id
from dual;
end;
/
4.新增数据
insert into test (name) values('苹果');
insert into test (name) values('香蕉');
5.查询数据
select * from test;
例2:通过触发器实现对表操作记录:
1.创建日志表
create table dept_log(
name varchar2(20),
time date
);
2.创建触发器
create or replace trigger dept_log
before delete or insert or update on dept
declare val varchar2(20);
begin
if inserting then
val := '插入一条数据';
elsif updating then
val := '修改一条数据';
elsif deleting then
val := '删除一条数据';
end if;
insert into dept_log values(val,sysdate);
end;
/
3.对表进行操作
insert into dept values(60,'市场部','南京');
update dept set loc = '北京' where deptno = 60;
delete from dept where deptno = 60;
4.查询日志表
select * from dept_log;
4 Oracle和Mysql的区别
- Oracle有表空间而Mysql不存在
- Oracle主键自增通过序列实现,调用下一个值nextVal;Mysql直接使用autoincrement实现主键自增
- Oracle字符(串)仅能使用单引号的处理,Mysql可以用双引号包起字符(串)
- 分页的SQL语句的处理,Mysql处理分页的SQL语句比较简单,使用LIMIT开始位置,记录个数;Oracle处理分页比较繁琐,使用伪列的rownum字段标明它的位置,且rownum的不等号只能>=0、>=1以及<=任意数,分页需嵌套子查询。
5 SQL语句的优化
- 建议少用‘*’代替所有列名
- 用exitsts代替in
- 连表查询的时候尽量减少表的查询次数
- 用truncate代替delete
- 合理使用索引,数据库会在具有唯一性的列上自动添加唯一性索引。索引能够更快的定位到查询数据,有效提高查询效率。但增删改数据的时候,数据库会浪费资源去维护索引。所以在数据量比较少不需要加索引,数据量比较多,查询比较多,增删改比较少的列适合添加索引
- sql语句尽量大写,Oracle会把所有语句转换成大写然后在执行
- 在保证语句完整的情况下,尽量多使用commit(多用在begin…end)
- 优化group by,将不需要的数据尽量在group by之前过滤掉
- 连表查询的时候尽量使用表的别名,减少解析时间
- 表连接在where条件之前(这是一个硬性条件)。and连接条件时,where条件能够过滤掉更多数据的条件放在最开始(得到数据少的先使用where过滤掉)