关于Primary Key测试

关于Oracle数据库表的主键,通常可以理解为非空且唯一,关于这种理解是否准确,请看下面的测试!

################################ 默认情况 #################################
lynn@10G> create table t1 (id number(8) primary key,name varchar2(10));

Table created.

lynn@10G> desc t1
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 ID                                                    NOT NULL NUMBER(8)
 NAME                                                           VARCHAR2(10)

lynn@10G> insert into t1 values (1,'aa');

1 row created.

lynn@10G> insert into t1 values (2,'bb');

1 row created.

lynn@10G> select * from t1;

        ID NAME
---------- ----------
         1 aa
         2 bb

lynn@10G> select INDEX_NAME,INDEX_TYPE,TABLE_OWNER,TABLE_NAME,TABLE_TYPE,UNIQUENESS from user_indexes where TABLE_NAME='T1';

INDEX_NAME      INDEX_TYPE TABLE_OWNE TABLE_NAME TABLE_TYPE  UNIQUENES
--------------- ---------- ---------- ---------- ----------- ---------
SYS_C005647     NORMAL     LYNN       T1         TABLE       UNIQUE

lynn@10G> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME from user_constraints where TABLE_NAME='T1';

OWNER                          CONSTRAINT_NAME                C TABLE_NAME
------------------------------ ------------------------------ - ----------
LYNN                           SYS_C005647                    P T1

lynn@10G> drop index SYS_C005647;
drop index SYS_C005647
           *
ERROR at line 1:
ORA-02429: cannot drop index used for enforcement of unique/primary key

lynn@10G> alter table t1 drop primary key;

Table altered.

lynn@10G> select INDEX_NAME,INDEX_TYPE,TABLE_OWNER,TABLE_NAME,TABLE_TYPE,UNIQUENESS from user_indexes where TABLE_NAME='T1';

no rows selected

lynn@10G> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME from user_constraints where TABLE_NAME='T1';

no rows selected


##################### 创建表时同时创建索引并指定给主键列 #####################
lynn@10G> CREATE TABLE t2
  2    (
  3      id NUMBER(8) PRIMARY KEY USING INDEX
  4      (CREATE INDEX t2_indx ON t2
  5        (id
  6        )
  7      ),
  8      name VARCHAR2(10)
  9    );

Table created.

lynn@10G> desc t2
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 ID                                                    NOT NULL NUMBER(8)
 NAME                                                           VARCHAR2(10)

lynn@10G> insert into t2 values(1,'aa');

1 row created.

lynn@10G> insert into t2 values(2,'bb');

1 row created.

lynn@10G> insert into t2 values(2,'bb');
insert into t2 values(2,'bb')
*
ERROR at line 1:
ORA-00001: unique constraint (LYNN.SYS_C005649) violated


lynn@10G> select * from t2;

        ID NAME
---------- ----------
         1 aa
         2 bb

lynn@10G> select INDEX_NAME,INDEX_TYPE,TABLE_OWNER,TABLE_NAME,TABLE_TYPE,UNIQUENESS from user_indexes where TABLE_NAME='T2';

INDEX_NAME      INDEX_TYPE TABLE_OWNE TABLE_NAME TABLE_TYPE  UNIQUENES
--------------- ---------- ---------- ---------- ----------- ---------
T2_INDX         NORMAL     LYNN       T2         TABLE       NONUNIQUE

lynn@10G> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME from user_constraints where TABLE_NAME='T2';

OWNER                          CONSTRAINT_NAME                C TABLE_NAME
------------------------------ ------------------------------ - ----------
LYNN                           SYS_C005649                    P T2

lynn@10G> drop index T2_INDX;
drop index T2_INDX
           *
ERROR at line 1:
ORA-02429: cannot drop index used for enforcement of unique/primary key

lynn@10G> alter table t2 drop primary key;

Table altered.

lynn@10G> select INDEX_NAME,INDEX_TYPE,TABLE_OWNER,TABLE_NAME,TABLE_TYPE,UNIQUENESS from user_indexes where TABLE_NAME='T2';

INDEX_NAME      INDEX_TYPE TABLE_OWNE TABLE_NAME TABLE_TYPE  UNIQUENES
--------------- ---------- ---------- ---------- ----------- ---------
T2_INDX         NORMAL     LYNN       T2         TABLE       NONUNIQUE

lynn@10G> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME from user_constraints where TABLE_NAME='T2';

no rows selected


################### 先创建表 | 再创建索引 | 再指定给主键列 ###################
lynn@10G> create table t3 (id number(8),name varchar2(10));

Table created.

lynn@10G> insert into t3 values (1,'aa');

1 row created.

lynn@10G> insert into t3 values (2,'bb');

1 row created.

lynn@10G> desc t3
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 ID                                                             NUMBER(8)
 NAME                                                           VARCHAR2(10)

lynn@10G> create bitmap index t3_indx on t3(id);

Index created.

lynn@10G> alter table t3 add primary key(id) using index t3_indx;
alter table t3 add primary key(id) using index t3_indx
*
ERROR at line 1:
ORA-14196: Specified index cannot be used to enforce the constraint.

lynn@10G> drop index t3_indx;

Index dropped.

lynn@10G> create index t3_indx on t3(id) reverse;

Index created.

lynn@10G> alter table t3 add primary key(id) using index t3_indx;

Table altered.

lynn@10G> desc t3
 Name                                                  Null?    Type
 ----------------------------------------------------- -------- ------------------------------------
 ID                                                    NOT NULL NUMBER(8)
 NAME                                                           VARCHAR2(10)

lynn@10G> select INDEX_NAME,INDEX_TYPE,TABLE_OWNER,TABLE_NAME,TABLE_TYPE,UNIQUENESS from user_indexes where TABLE_NAME='T3';

INDEX_NAME      INDEX_TYPE TABLE_OWNE TABLE_NAME TABLE_TYPE  UNIQUENES
--------------- ---------- ---------- ---------- ----------- ---------
T3_INDX         NORMAL/REV LYNN       T3         TABLE       NONUNIQUE

lynn@10G> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME from user_constraints where TABLE_NAME='T3';

OWNER                          CONSTRAINT_NAME                C TABLE_NAME
------------------------------ ------------------------------ - ----------
LYNN                           SYS_C005651                    P T3

lynn@10G> drop index t3_indx;
drop index t3_indx
           *
ERROR at line 1:
ORA-02429: cannot drop index used for enforcement of unique/primary key

lynn@10G> alter table t3 drop constraint SYS_C005651;

Table altered.

lynn@10G> select OWNER,CONSTRAINT_NAME,CONSTRAINT_TYPE,TABLE_NAME from user_constraints where TABLE_NAME='T3';

no rows selected

lynn@10G> select INDEX_NAME,INDEX_TYPE,TABLE_OWNER,TABLE_NAME,TABLE_TYPE,UNIQUENESS from user_indexes where TABLE_NAME='T3';

INDEX_NAME      INDEX_TYPE TABLE_OWNE TABLE_NAME TABLE_TYPE  UNIQUENES
--------------- ---------- ---------- ---------- ----------- ---------
T3_INDX         NORMAL/REV LYNN       T3         TABLE       NONUNIQUE

lynn@10G> drop index t3_indx;

Index dropped.

lynn@10G> create index t3_indx on t3 (round(id,0));

Index created.

lynn@10G> alter table t3 add primary key(id) using index t3_indx;
alter table t3 add primary key(id) using index t3_indx
*
ERROR at line 1:
ORA-14196: Specified index cannot be used to enforce the constraint.

############################## 主键测试结论 ###############################
关于主键的官方解释链接:
http://docs.oracle.com/cd/E11882_01/server.112/e40540/datainte.htm#CNCPT322
http://docs.oracle.com/cd/E11882_01/server.112/e40540/datainte.htm#CNCPT1646
http://docs.oracle.com/cd/E11882_01/server.112/e41084/clauses002.htm#SQLRF52180

To enable a unique or primary key constraint, you must have the privileges necessary to create an index on the table. You need these privileges because Oracle Database creates an index on the columns of the unique or primary key in the schema containing the table.

primary key 可理解为如下形式:
not null constraint + unique constraint + index

1.虽然这个index可以不是unique,但却必须存在,对于Oracle DB而言,它认为这个index是unique的,这个索引不能是函数和位图索引;
2.如果主键列上的索引是人为指定创建的,当主键约束被删除后,主键列上的索引不会像默认情况那样也被删除;
3.通常理解的primary key是not null + unique index也没错,因为not null + unique index可以实现主键的作用,但是主键的唯一性不是通过主键列上的这个index来保证实现,而是通过主键约束本身来保证唯一性的!

发表评论

电子邮件地址不会被公开。

您可以使用这些HTML标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>