一般,我们看到术语“索引”和“键”交换使用,但实际上这两个是不同的。索引是存储在数据库中的一个物理结构,键纯粹是一个逻辑概念。键代表创建来实施业务规则的完整性约束。索引和键的混淆通常是由于数据库使用索引来实施完整性约束。
推荐阅读:
oracle主键约束自动建立索引问题
oracle 10g删除主键约束后无法删除唯一约束索引问题的模拟与分析
介绍oracle virtual index虚拟索引
oracle中检查是否需要重构索引
oracle case when索引 空值索引 位图索引
oracle分析表和索引
oracle主键约束自动建立索引问题
接下来我们看看数据库中的主键约束、唯一键约束和唯一索引的区别。
sql> select * from v$version;
banner
--------------------------------------------------------------------------------
oracle database 11g enterprise edition release 11.2.0.1.0 - production
pl/sql release 11.2.0.1.0 - production
core 11.2.0.1.0 production
tns for linux: version 11.2.0.1.0 - production
nlsrtl version 11.2.0.1.0 - production
sql> create table test (
2 id int,
3 name varchar2(20),
4 constraint pk_test primary key(id))
5 tablespace users;
table created.
sql> select constraint_name, constraint_type from user_constraints;
constraint_name c
------------------------------ -
pk_test p
在test表中,我们指定了id列作为主键,oracle数据库会自动创建一个同名的唯一索引:
sql> select index_name, index_type, uniqueness, tablespace_name
2 from user_indexes
3 where table_owner='scott'
4 and table_name = 'test';
index_name index_type uniquenes tablespace_name
-------------------- -------------------- --------- ------------------------------
pk_test normal unique users
此时,如果我们再试图在id列上创建一个唯一索引,oracle会报错,因为该列上已经存在一个唯一索引:
sql> create unique index idx_test_uk on test(id);
create unique index idx_test_uk on test(id)
*
error at line 1:
ora-01408: such column list already indexed
即使创建非唯一索引也不行:
sql> create index idx_test_id on test(id);
create index idx_test_id on test(id)
*
error at line 1:
ora-01408: such column list already indexed
那么唯一键约束的情况是怎样的呢?
sql> drop table test purge;
table dropped.
sql> create table test(
2 id int,
3 name varchar2(20),
4 constraint uk_test unique(id));
table created.
sql> select constraint_name, constraint_type from user_constraints;
constraint_name c
------------------------------ -
uk_test u
查看此时的索引情况:
sql> select index_name, index_type, uniqueness, tablespace_name
2 from user_indexes
3 where table_owner='scott'
4 and table_name = 'test';
index_name index_type uniquenes tablespace_name
-------------------- -------------------- --------- ------------------------------
uk_test normal unique users
oracle同样自动创建了一个同名的唯一索引,而且也不允许再在此列上创建唯一索引或非唯一索引。
我们知道,主键约束要求列值非空(not null),那么唯一键约束是否也要求非空呢?
sql> insert into test values(1, 'sally');
1 row created.
sql> insert into test values(null, 'tony');
1 row created.
sql> insert into test values(null, 'jack');
1 row created.
sql> select * from test;
id name
---------- --------------------
1 sally
tony
jack
从实验结果来看,唯一键约束并没有非空要求。
接下来我们看看唯一索引对列值的非空要求有什么不同。
sql> drop table test purge;
table dropped.
sql> create table test(
2 id int,
3 name varchar2(20));
table created.
sql> create unique index idx_test_id on test (id);
index created.
sql> insert into test values(1, 'sally');
1 row created.
sql> insert into test values(null, 'tony');
1 row created.
sql> insert into test values(null, 'jack');
1 row created.
sql> select * from test;
id name
---------- --------------------
1 sally
tony
jack
通过实验,我们看出唯一索引与唯一键约束一样对列值非空不做要求。
继续阅读本文的精彩内容请看第2页:
,
