本文内容多选自网络(百度百科及其它博主)
在看索引之前,听说这个超难,又是聚簇索引、又是唯一索引、还有普通索引……其实看下来,感觉索引定义乱七八糟的原因,纯粹是外国的东西来到中国之后,语义产生的偏差和个人不同的理解。
索引
撇开别的不谈,只看索引,英文名是Index,Index通常用于存放数据的位置,就比如Java的List,get()的参数就是一个Index,Index不是我们要查找的值,但是通过Index可以帮我们找到具体的值,而数据库中,索引就是这样一种帮我们快速查找一个行的数据库结构,它是一种数据结构,一种快速检索的数据结构。
--创建普通索引 CREATE INDEX TABLE1_T_NAME_UX ON TABLE1(T_NAME); --删除索引 DROP INDEX TABLE1_T_NAME_UX;
使用CREATE INDEX创建普通索引,既没有唯一约束,也不具备聚簇的特点(非聚簇索引,索引值可以重复)。
如果要建立特殊的索引,则需要显示的写出关键字,CREATE UNIQUE INDEX建立唯一索引。
唯一索引
“唯一索引”,这显然是两个名词,“索引”的作用如前面所说,帮我们增加查询效率,而“唯一”让人想到的是另一个专业名词:“唯一约束”,那不妨先看看什么是唯一约束。
--建立唯一约束 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;
其实当创建主键约束或者是唯一约束时,oracle会自动创建一个同名的索引,且该索引就是唯一索引。
关于Oracle帮我们自动创建索引的合理性分析:
要保证数据唯一,在新增数据时,就必须判断新数据是否已经存在,如果不存在则插入成功,否则插入失败。
判断数据是否存在的方式就是进行全表查询,提高查询效率的方式就是创建索引,要保证唯一而不失效率的做法就是添加索引,因此自动添加索引是合理的。
--从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)
值得注意的是,经过测试,唯一索引中空值可以有多行,与部分文章描述不相符
聚簇索引
聚簇索引的“聚簇”其实也是一个名词,指的是为了提高某个属性(或属性组)的查询速度,把这个或这些属性(称为聚簇码)上具有相同值的元组集中存放在连续的物理块。
关于聚簇的理解:
聚簇功能可以大大提高按聚簇码进行查询的效率。例如要查询信息系的所有学生名单,设信息系有500名学生,在极端情况下,这500名学生所对应的数据元组分布在500个不同的物理块上。尽管对学生关系已按所在系建有索引,由索引很快找到了信息系学生的元组标识,避免了全表扫描,然而再由元组标识去访问数据块时就要存取500个物理块,执行500次I/O操作。如果将同一系的学生元组集中存放,则每读一个物理块可得到多个满足查询条件的元组,从而显著地减少了访问磁盘的次数。
Oracle中簇可以单独定义,索引也可以单独定义,两者又可以共同使用,簇决定了物理顺序,而索引增加查询效率。
-- 在Oracle当中,聚簇不是索引的组织形式,而是表的组织形式。
-- 一个表只能有一个聚簇索引,但是,一个聚簇索引可以包含多个列,称为组合索引。
-- 保证两个表的记录按照T_NAME值尽量存放到同一个物理块当中,让两个表同时用上簇。
-- 两个表有一个字段完全相同,并且在业务中经常会按这个字段为目标连接这两个表,
-- 建立聚簇表,两个表公用一个字段,能减少占用空间,并能明显提高连接查询速度。
--创建一个簇 CREATE CLUSTER CLUSTER_T_NAME(T_NAME VARCHAR2(50)); --查询已有的簇 select * from user_clusters; --在表1中使用簇,表在建索引之前不可用 CREATE TABLE TABLE1 ( T_NAME VARCHAR2(50), T_AGE NUMBER )CLUSTER CLUSTER_T_NAME(T_NAME); --在表2中使用簇,表在建索引之前不可用 CREATE TABLE TABLE2 ( T_NAME VARCHAR2(50), T_GENDER NUMBER )CLUSTER CLUSTER_T_NAME(T_NAME); --在簇上添加索引 CREATE INDEX CLUSTER_T_NAME_INDEX ON CLUSTER CLUSTER_T_NAME; DROP TABLE TABLE1; DROP TABLE TABLE2; --先删表,再删簇 DROP CLUSTER CLUSTER_T_NAME;