刚刚看完文档中这部分的描述,简单总结一下。如无特别说明,这里的主键泛指主键和唯一约束。
这一篇介绍主键删除对索引的影响。
主键与索引(一):http://yangtingkun.itpub.net/post/468/519116
主键与索引(二):http://yangtingkun.itpub.net/post/468/519129
前面两篇文章介绍了主键创建时如何影响索引,这里讨论一下删除主键时,会对索引造成何种的影响。
SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));
表已创建。
SQL>
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, INDEX_NAME
2
FROM USER_CONSTRAINTS
3
WHERE TABLE_NAME = 'T';
CONSTRAINT_NAME C INDEX_NAME
------------------------------ - ------------------------------
SYS_C007457 P
SYS_C007457
SQL>
SELECT INDEX_NAME, UNIQUENESS, TABLESPACE_NAME
2
FROM USER_INDEXES
3
WHERE TABLE_NAME = 'T';
INDEX_NAME UNIQUENES TABLESPACE_NAME
------------------------------ --------- -----------------------------
SYS_C007457
UNIQUE USERS
SQL> ALTER TABLE T DROP PRIMARY KEY;
表已更改。
SQL>
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, INDEX_NAME
2
FROM USER_CONSTRAINTS
3
WHERE TABLE_NAME = 'T';
未选定行
SQL>
SELECT INDEX_NAME, UNIQUENESS, TABLESPACE_NAME
2
FROM USER_INDEXES
3
WHERE TABLE_NAME = 'T';
未选定行
可以看到,由于添加主键自动创建的索引在主键删除的时候也会被删除。
当然可以通过KEEP INDEX的方式来改变默认Oracle的默认行为,保留索引的存在:
SQL> ALTER TABLE T ADD PRIMARY KEY (ID);
表已更改。
SQL>
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, INDEX_NAME
2
FROM USER_CONSTRAINTS
3
WHERE TABLE_NAME = 'T';
CONSTRAINT_NAME C INDEX_NAME
------------------------------ - ------------------------------
SYS_C007458 P
SYS_C007458
SQL>
SELECT INDEX_NAME, UNIQUENESS, TABLESPACE_NAME
2
FROM USER_INDEXES
3
WHERE TABLE_NAME = 'T';
INDEX_NAME UNIQUENES TABLESPACE_NAME
------------------------------ --------- -----------------------
SYS_C007458
UNIQUE USERS
SQL> ALTER TABLE T DROP PRIMARY KEY KEEP INDEX;
表已更改。
SQL>
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, INDEX_NAME
2
FROM USER_CONSTRAINTS
3
WHERE TABLE_NAME = 'T';
未选定行
SQL>
SELECT INDEX_NAME, UNIQUENESS, TABLESPACE_NAME
2
FROM USER_INDEXES
3
WHERE TABLE_NAME = 'T';
INDEX_NAME UNIQUENES TABLESPACE_NAME
------------------------------ --------- -----------------------
SYS_C007458
UNIQUE USERS
下面看看已有索引的情况:
SQL> DROP TABLE T PURGE;
表已删除。
SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30));
表已创建。
SQL> CREATE INDEX IND_T_ID ON T (ID);
索引已创建。
SQL> ALTER TABLE T ADD PRIMARY KEY (ID) USING INDEX IND_T_ID;
表已更改。
SQL>
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, INDEX_NAME
2
FROM USER_CONSTRAINTS
3
WHERE TABLE_NAME = 'T';
CONSTRAINT_NAME C INDEX_NAME
------------------------------ - ------------------------------
SYS_C007459 P IND_T_ID
SQL>
SELECT INDEX_NAME, UNIQUENESS, TABLESPACE_NAME
2
FROM USER_INDEXES
3
WHERE TABLE_NAME = 'T';
INDEX_NAME UNIQUENES TABLESPACE_NAME
------------------------------ --------- --------------------------
IND_T_ID NONUNIQUE USERS
SQL> ALTER TABLE T DROP PRIMARY KEY;
表已更改。
SQL>
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, INDEX_NAME
2
FROM USER_CONSTRAINTS
3
WHERE TABLE_NAME = 'T';
未选定行
SQL>
SELECT INDEX_NAME, UNIQUENESS, TABLESPACE_NAME
2
FROM USER_INDEXES
3
WHERE TABLE_NAME = 'T';
INDEX_NAME UNIQUENES TABLESPACE_NAME
------------------------------ --------- --------------------------
IND_T_ID NONUNIQUE
USERS
对于用户手工创建的索引,在约束删除的时候并不会被删除。
同样可以通过DROP INDEX的方式来改变Oracle的默认行为:
SQL> ALTER TABLE T ADD PRIMARY KEY (ID) USING INDEX IND_T_ID;
表已更改。
SQL>
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, INDEX_NAME
2
FROM USER_CONSTRAINTS
3
WHERE TABLE_NAME = 'T';
CONSTRAINT_NAME C INDEX_NAME
------------------------------ - ------------------------------
SYS_C007460 P IND_T_ID
SQL>
SELECT INDEX_NAME, UNIQUENESS, TABLESPACE_NAME
2
FROM USER_INDEXES
3
WHERE TABLE_NAME = 'T';
INDEX_NAME UNIQUENES TABLESPACE_NAME
------------------------------ --------- ----------------------------------
IND_T_ID NONUNIQUE
USERS
SQL> ALTER TABLE T DROP PRIMARY KEY DROP INDEX;
表已更改。
SQL>
SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE, INDEX_NAME
2
FROM USER_CONSTRAINTS
3
WHERE TABLE_NAME = 'T';
未选定行
SQL>
SELECT INDEX_NAME, UNIQUENESS, TABLESPACE_NAME
2
FROM USER_INDEXES
3
WHERE TABLE_NAME = 'T';
未选定行