接下来我们看看数据库中的主键约束、唯一键约束和唯一索引的区别。
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.