Oracle:启用 PK 会重建其索引吗?

Tul*_*ova 2 index oracle constraint

设想:

  • MY_TABLE有主键约束PK_MY_TABLE
  • MY_TABLE还有一个名为的索引IDX_PK_MY_TABLE,用于强制约束的唯一性PK_MY_TABLE

如果我禁用约束PK_MY_TABLE然后重新启用它,索引IDX_PK_MY_TABLE会重建吗?

Phi*_*lᵀᴹ 6

它很容易测试。

有两种可能的情况。

场景一:

场景 1 是使用现有索引创建 PK:

SQL> create table MY_TABLE
  2  (
  3  pk number
  4  );

Table created.

SQL>
Run Code Online (Sandbox Code Playgroud)

给它添加索引:

SQL> create unique index IDX_PK_MY_TABLE on MY_TABLE (pk);

Index created.

SQL>
Run Code Online (Sandbox Code Playgroud)

添加约束:

SQL> alter table MY_TABLE add constraint PK_MY_TABLE primary key (pk) USING INDE
X  IDX_PK_MY_TABLE;

Table altered.

SQL> select constraint_name from user_constraints;

CONSTRAINT_NAME
------------------------------
PK_MY_TABLE

SQL>
SQL>
SQL> select index_name
  2  from user_indexes;

INDEX_NAME
------------------------------
IDX_PK_MY_TABLE
Run Code Online (Sandbox Code Playgroud)

插入一些数据:

SQL> insert into MY_TABLE values(1);

1 row created.

SQL> insert into MY_TABLE values(2);

1 row created.

SQL>
Run Code Online (Sandbox Code Playgroud)

测试约束:

SQL> insert into MY_TABLE values(2);
insert into MY_TABLE values(2)
*
ERROR at line 1:
ORA-00001: unique constraint (PHIL.PK_MY_TABLE) violated

SQL>
Run Code Online (Sandbox Code Playgroud)

禁用约束:

SQL>
SQL> alter table MY_TABLE disable constraint PK_MY_TABLE;

Table altered.

SQL> 
Run Code Online (Sandbox Code Playgroud)

再试INSERT一次:

SQL> insert into MY_TABLE values(2);
insert into MY_TABLE values(2)
*
ERROR at line 1:
ORA-00001: unique constraint (PHIL.IDX_PK_MY_TABLE) violated
Run Code Online (Sandbox Code Playgroud)

它成功是因为在禁用约束时未禁用/删除唯一索引。请注意,原始错误是 ORA-00001: unique constraint (PHIL.PK_MY_TABLE) violated,而PHIL.IDX_PK_MY_TABLE一旦禁用 PK 约束,就会违反索引约束。

场景2:

场景 2 是在创建表时创建 PK:

SQL> create table MY_TABLE
  2  (
  3  pk number,
  4  constraint PK_MY_TABLE PRIMARY KEY (pk)
  5  );

Table created.

SQL> select index_name from user_indexes;

INDEX_NAME
------------------------------
PK_MY_TABLE

SQL> select constraint_name from user_constraints;

CONSTRAINT_NAME
------------------------------
PK_MY_TABLE

SQL> 
Run Code Online (Sandbox Code Playgroud)

禁用约束:

SQL> alter table MY_TABLE disable constraint PK_MY_TABLE;

Table altered.

SQL> select constraint_name, status from user_constraints;

CONSTRAINT_NAME                STATUS
------------------------------ --------
PK_MY_TABLE                    DISABLED

SQL>
Run Code Online (Sandbox Code Playgroud)

索引不见了!:

SQL>  select index_name from user_indexes;

no rows selected

SQL>
Run Code Online (Sandbox Code Playgroud)

重新启用它会重新创建索引:

SQL> alter table MY_TABLE enable constraint PK_MY_TABLE;

Table altered.

SQL> select index_name from user_indexes;

INDEX_NAME
------------------------------
PK_MY_TABLE

SQL>
Run Code Online (Sandbox Code Playgroud)

如果要保留索引:

SQL> alter table MY_TABLE disable constraint PK_MY_TABLE  keep index;

Table altered.

SQL> select index_name from user_indexes;

INDEX_NAME
------------------------------
PK_MY_TABLE

SQL>
Run Code Online (Sandbox Code Playgroud)