oracle - 浅谈索引
索引本身非常复杂,外国的东西来到中国之后,语义产生的偏差,加上个人不同的理解,网络上索引的相关知识就显得特别乱。
(代码部分为 Oracle 语法)
索引
索引,就像书本上的目录,用于辅助快速找到所需的数据。
索引的创建与使用,就像刚学编程的时候,把数据从小到大排列,然后创建一个数组,把数据放进去,最后进行折半查找。
创建索引的过程:确定数据排序规则 => 选用适当的数据结构 => 使用索引查找数据。
简单分类
-
算法原理上看,分为 b-tree 、bitmap、hash、全文检索等等,想要深层了解索引,最好从算法开始学。
-
然后,索引有不同的应用场景,算法本质不变,但是结合业务场景做了调整,比如:
* 普通索引,就是很纯粹的索引;
* 唯一索引(主键),主键约束和唯一约束,需要索引支持,默认会添加索引;
* 函数索引,经常使用函数进行查询 (比如:substr),则考虑使用函数索引;
* 聚簇索引,将数据存储在连续的磁盘单元上;
- 最后,是一些更加特殊场景,如果建立了分区,需要使用分区索引(Hash 索引),如果考虑开发全文检索的功能,就要使用域索引。
更细致划分(面试)
大学考试或者面试可能会遇到:
- 聚簇索引和非聚簇索引。
(这种分类方式有一定道理,因为聚簇索引是极其特殊的存在)
- 根据列的性质划分,分为:普通索引、唯一索引、主键索引、域索引。
(有些教学视频会这么划分)
- 按照字段个数,分为:单列索引和联合索引。
(划分的意义?)
普通索引
--创建普通索引
CREATE INDEX TABLE1_T_NAME_UX ON TABLE1 (T_NAME);
--删除索引
DROP INDEX TABLE1_T_NAME_UX;
使用 CREATE INDEX 创建普通索引,既没有唯一约束,也不具备举聚簇的特点。
聚簇索引
聚簇索引是极其特殊的存在,三大数据库:mysql、oracle、sqlserver,实现方式都不相同。
直接说聚簇(clustering),可能理解不来,其实这个单词很常见,你把它翻译成集群,一下子就记住了,cluster 也有集群的意思。
简单地说:聚簇就是将数据集中存放在连续的物理块(一种数据存放方式)。
连续的物理块要怎么理解?我们能想到很多种方式:
- 把所有的主键,存放在连续的物理块?
- 主键其实不连续,但是主键跟所指向的那一行数据,存放在连续的物理块?
- 还是说,要把表中的每一行数据,存放在连续的物理块?(正确)
第三种说法是对的,聚簇索引会重新组织表的数据行,使它们按照索引键的顺序存储在磁盘上。
因为会对所有的数据排序,因此说,聚簇索引只能存在一个。
聚簇的优点:
前面的说法,有些抽象,可能理解不了聚簇的作用。
就以语文书为例,假设你的目录是这样,是不是看着很难受?
1. 静夜思…………120
2. 锄禾………………3
3. 将进酒…………32
你肯定是希望,书本的内容顺序,跟目录是一样。
索引决定了书本目录要怎么设计,而聚簇,决定了书本内容的排版方式。
还是前面那句话,三大数据库:mysql、oracle、sqlserver,最终实现方式都不相同,仍然可以进一步深入研究。
唯一索引
唯一索引(unique index),提到唯一索引,就不得不提唯一约束, 唯一约束就是在索引算法基础上,额外进行了一次判断,如果出现重复数据就报错。
如果我们细细观察,就会发现:当我们创建唯一约束时,oracle 会自动创建一个同名的索引,且该索引就是唯一索引。
为什么创建唯一约束的时候,需要默认添加索引?这样做有什么说法?
要保证数据唯一,就需要在新增的时候,把所有的数据查询一遍,如果已经存在,就抛出异常。 数据查询的过程,是十分耗时的,而索引功能,就是为了提高查询效率。
因此,有必要在创建主键,或者唯一索引的时候,默认添加索引。
--建立唯一约束
ALTER TABLE TABLE1
ADD CONSTRAINT TABLE1_NAME_CONSTRAINT UNIQUE (T_NAME);
ALTER TABLE TABLE1
ADD UNIQUE (T_NAME);
--删除立唯一约束
ALTER TABLE TABLE1
DROP CONSTRAINT TABLE1_NAME_CONSTRAINT;
--建表的时候创建唯一约束
CREATE TABLE EXAMPLE_TABLE
(
T_NAME number not null,
T_AGE number,
CONSTRAINT EXAMPLE_TABLE_T_NAME_CT UNIQUE (T_NAME)
);
DROP TABLE EXAMPLE_TABLE;
--禁用
ALTER TABLE TABLE1
DISABLE CONSTRAINT TABLE1_NAME_CONSTRAINT;
--启用
ALTER TABLE TABLE1
ENABLE CONSTRAINT TABLE1_NAME_CONSTRAINT;
--从user_indexes 和user_ind_columns 查找索引
select *
from user_indexes
where table_name = 'TABLE1';
select *
from user_ind_columns t;
--创建唯一索引的简写方式
CREATE UNIQUE INDEX TABLE1_T_NAME_UX ON TABLE1 (T_NAME)
函数索引
-- 如果查询过程中,经常对字段进行处理,比如:字符串截取
select *
from employee
where substr(ename, 1, 2) = 'XX';
-- 这时候就可以创建函数索引,这样,执行上面的查询语句时,索引就能排上用场
create index employee_ename_substr on eemp (substr(ename, 1, 2));