Oracle添加主键和唯一约束最佳实践

经常有开发人员找DBA,需要把唯一索引改为普通索引,或者把主键改为唯一索引或普通索引...

主键属性:普通索引+唯一约束+not null约束 或者唯一索引+not null约束

唯一索引属性:普通索引+唯一约束

最佳实践:

主键用唯一索引+主键约束两步骤来创建,可直接变更为唯一索引

唯一索引用普通索引+唯一约束两步骤来创建,可以直接变更为普通索引

主键不同创建方式,不同的ddl变更结果:测试表如下

create table TEST01
(
  col_date date,
  col2_str VARCHAR2(100),
  col3_str VARCHAR2(40),
  col4_str VARCHAR2(40),
  col5_str VARCHAR2(40)
);

1)、直接添加主键约束

alter table TEST01 add constraint PK_TEST01 primary key (COL_DATE);
--查看该表上索引情况
set linesize 400
col owner for a10
col index_name for a20
col index_type for a10
col table_owner for a10
col table_name for a20
col uniqueness for a10
col constraint_name for a20
col constraint_type for a10
col index_owner for a10
col STATUS for a10
select owner,index_name,index_type,table_owner,table_name,uniqueness from DBA_INDEXES where table_name='TEST01';

OWNER      INDEX_NAME           INDEX_TYPE TABLE_OWNE TABLE_NAME           UNIQUENESS
---------- -------------------- ---------- ---------- -------------------- ----------
SCOTT      PK_TEST01            NORMAL     SCOTT      TEST01               UNIQUE
--查看下该表上约束情况
OWNER      CONSTRAINT_NAME      CONSTRAINT TABLE_NAME           INDEX_OWNE INDEX_NAME           STATUS
---------- -------------------- ---------- -------------------- ---------- -------------------- ----------
SCOTT      PK_TEST01            P          TEST01               SCOTT      PK_TEST01            ENABLED
可以看到直接添加主键约束后,Oracle会自动帮你创建一个和约束名相同的唯一索引,并且添加了主键约束。

能否把主键直接变更为唯一索引?

alter table test01 disable constraint PK_TEST01;
--检查索引和约束情况
select owner,index_name,index_type,table_owner,table_name,uniqueness from DBA_INDEXES where table_name='TEST01';

no rows selected
select t.owner,t.constraint_name,t.constraint_type,t.table_name,t.index_owner,t.index_name,STATUS  from dba_constraints t where t.table_name='TEST01';

OWNER      CONSTRAINT_NAME      CONSTRAINT TABLE_NAME           INDEX_OWNE INDEX_NAME           STATUS
---------- -------------------- ---------- -------------------- ---------- -------------------- ----------
SCOTT      PK_TEST01            P          TEST01                                               DISABLED
可以看到没有索引了

结论:不能直接变更,禁用/删除主键约束后,会发现系统自动创建的唯一索引消失。

2)、创建唯一索引+主键约束

alter table test01 drop constraint PK_TEST01;
create unique index scott.uidx_col_date on scott.test01(col_date);
alter table TEST01 add constraint PK_TEST01 primary key (COL_DATE);
--检查索引和约束情况
select owner,index_name,index_type,table_owner,table_name,uniqueness from DBA_INDEXES where table_name='TEST01';

OWNER      INDEX_NAME           INDEX_TYPE TABLE_OWNE TABLE_NAME           UNIQUENESS
---------- -------------------- ---------- ---------- -------------------- ----------
SCOTT      UIDX_COL_DATE        NORMAL     SCOTT      TEST01               UNIQUE

select t.owner,t.constraint_name,t.constraint_type,t.table_name,t.index_owner,t.index_name,STATUS  from dba_constraints t where t.table_name='TEST01';

OWNER      CONSTRAINT_NAME      CONSTRAINT TABLE_NAME           INDEX_OWNE INDEX_NAME           STATUS
---------- -------------------- ---------- -------------------- ---------- -------------------- ----------
SCOTT      PK_TEST01            P          TEST01               SCOTT      UIDX_COL_DATE        ENABLED
可以看到主键约束中使用到了创建的唯一索引

能否把主键直接变更为唯一索引?

alter table test01 disable constraint PK_TEST01;
--检查索引和约束情况
select owner,index_name,index_type,table_owner,table_name,uniqueness from DBA_INDEXES where table_name='TEST01';

OWNER      INDEX_NAME           INDEX_TYPE TABLE_OWNE TABLE_NAME           UNIQUENESS
---------- -------------------- ---------- ---------- -------------------- ----------
SCOTT      UIDX_COL_DATE        NORMAL     SCOTT      TEST01               UNIQUE

select t.owner,t.constraint_name,t.constraint_type,t.table_name,t.index_owner,t.index_name,STATUS  from dba_constraints t where t.table_name='TEST01';

OWNER      CONSTRAINT_NAME      CONSTRAINT TABLE_NAME           INDEX_OWNE INDEX_NAME           STATUS
---------- -------------------- ---------- -------------------- ---------- -------------------- ----------
SCOTT      PK_TEST01            P          TEST01                                               DISABLED
可以看到创建的唯一索引还在的

结论:可以直接变更,禁用/删除主键约束后,会发现分开创建的唯一索引还在。

和主键创建方式类似,唯一索引也可以用普通索引+唯一约束来创建,好处是可以禁用/删除唯一约束,直接变更为普通索引

create index scott.idx_col_date on scott.test01(col_date);
alter table TEST01 add constraint UK_TEST01 unique (COL_DATE);
--检查索引和约束情况
select owner,index_name,index_type,table_owner,table_name,uniqueness from DBA_INDEXES where table_name='TEST01';

OWNER      INDEX_NAME           INDEX_TYPE TABLE_OWNE TABLE_NAME           UNIQUENESS
---------- -------------------- ---------- ---------- -------------------- ----------
SCOTT      IDX_COL_DATE         NORMAL     SCOTT      TEST01               NONUNIQUE

select t.owner,t.constraint_name,t.constraint_type,t.table_name,t.index_owner,t.index_name,STATUS  from dba_constraints t where t.table_name='TEST01';

OWNER      CONSTRAINT_NAME      CONSTRAINT TABLE_NAME           INDEX_OWNE INDEX_NAME           STATUS
---------- -------------------- ---------- -------------------- ---------- -------------------- ----------
SCOTT      UK_TEST01            U          TEST01               SCOTT      IDX_COL_DATE         ENABLED

猜你喜欢

转载自blog.csdn.net/u010033674/article/details/112993584