`
wsql
  • 浏览: 12035418 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

Oracle 唯一 约束(unique constraint) 与 索引(index) 关系说明

 
阅读更多

一. 官网对Unique Constraints说明

http://download.oracle.com/docs/cd/E11882_01/server.112/e16508/datainte.htm#CNCPT1642

uniquekey constraint requires that every value in a column or set of columns beunique. No rows of a table may have duplicate values in a column (the uniquekey) or set of columns (the composite unique key) with a unique key constraint.

Note:

Theterm key refers only to the columns defined in the integrity constraint.Because the database enforces a unique constraint byimplicitly creating or reusing anindexon the key columns,the term uniquekey is sometimes incorrectly used as a synonym for unique key constraint orunique index.

--数据库在创建unique constraint的同时,强制创建或者重用列上的索引。如果之前列上没有索引,那么强制创建的索引是unique index,如果列上已经存在索引,就重用之前的索引。

Uniquekey constraints are appropriate for any column where duplicate values are notallowed. Unique constraints differ from primary keyconstraints, whose purpose is to identify each table row uniquely, andtypically contain values that have no significance other than being unique.Examples of unique keys include:

(1)A customer phone number, where the primary key is the customernumber

(2)A department name, where the primary key is the department number

Asshown inExample2-1, a unique key constraint exists on the email column of the hr.employeestable. The relevant part of the statement is as follows:

CREATE TABLE employees ( ...

,email VARCHAR2(25)

CONSTRAINT emp_email_nn NOT NULL ...

,CONSTRAINT emp_email_uk UNIQUE (email) ... );

Theemp_email_uk constraint ensures that no two employees have the same emailaddress, as shown inExample5-1.

Example 5-1 Unique Constraint

SQL> SELECT employee_id, last_name,email FROM employees WHERE email = 'PFAY';

EMPLOYEE_ID LAST_NAME EMAIL

----------- --------------------------------------------------

202 Fay PFAY

SQL> INSERT INTO employees (employee_id,last_name, email, hire_date, job_id)

1 VALUES(999,'Fay','PFAY',SYSDATE,'ST_CLERK');

.

.

.

ERROR at line 1:

ORA-00001:unique constraint (HR.EMP_EMAIL_UK) violated

Unless a NOT NULLconstraint is also defined, a null always satisfies a unique key constraint.Thus,columns with both unique key constraints and NOT NULL constraints are typical.This combination forces the user to enter values in the unique key andeliminates the possibility that new row data conflicts with existing row data.

Note:

Because of the searchmechanism for unique key constraints on multiple columns, you cannot haveidentical values in the non-null columns of a partially null composite uniquekey constraint.

二. 相关测试

2.1 测试unique index 和 uniqueconstraint

SYS@anqing2(rac2)> create table ut(idnumber,phone varchar2(15),name varchar2(15));

Table created.

SYS@anqing2(rac2)> insert into utvalues(1,'13888888888','dave');

1 row created.

SYS@anqing2(rac2)> insert into utvalues(1,'13888888888','dave');

1 row created.

SYS@anqing2(rac2)> insert into utvalues(2,'13899999999','dba');

1 row created.

SYS@anqing2(rac2)> commit;

Commit complete.

--在phone 字段上,我们创建uniqueconstraint

SYS@anqing2(rac2)> alter table ut addconstraint uc_phone unique(phone);

alter table ut add constraint uc_phoneunique(phone)

*

ERROR at line 1:

ORA-02299: cannot validate (SYS.UC_PHONE) -duplicate keys found

--这里报错,因为我们在插入数据的时候,有重复值,先删除掉重复值

SYS@anqing2(rac2)> select * from ut;

ID PHONE NAME

---------- --------------- ---------------

1 13888888888 dave

2 13899999999 dba

1 13888888888 dave

SYS@anqing2(rac2)> delete from ut whererownum=1;

1 row deleted.

SYS@anqing2(rac2)> commit;

Commit complete.

SYS@anqing2(rac2)> select * from ut;

ID PHONE NAME

---------- --------------- ---------------

2 13899999999 dba

1 13888888888 dave

--唯一性约束创建成功

SYS@anqing2(rac2)> alter table ut addconstraint uc_phone unique(phone);

Table altered.

--查看约束

SYS@anqing2(rac2)> selectconstraint_name,constraint_type,table_name,index_owner,index_name fromuser_constraints where table_name = 'UT';

CONSTRAINT_NAME C TABLE_NAME INDEX_OWNERINDEX_NAME

--------------- - -------------------------- -------------

UC_PHONE U UT SYS UC_PHONE

--Oracle 自动创建了索引并关联到约束, 索引名和约束名是相同的。

--验证下索引

SYS@anqing2(rac2)> selectindex_name,index_type,uniqueness,generated from user_indexes wheretable_name='UT';

INDEX_NAME INDEX_TYPE UNIQUENES GENERATED

------------- ------------- -------------------

UC_PHONE NORMAL UNIQUE N

--我们并没有创建索引,而是在创建unique constraint时,oracle 强制创建了uniqueindex。

--现在我们drop index 看看

SYS@anqing2(rac2)> drop index uc_phone;

drop index uc_phone

*

ERROR at line 1:

ORA-02429: cannot drop index used forenforcement of unique/primary key

--这里报错,不能删除unique/primary key 上的索引。在这种情况下,我们只有先删除约束。

SYS@anqing2(rac2)> alter table ut dropconstraint uc_phone;

Table altered.

SYS@anqing2(rac2)> drop index uc_phone;

drop index uc_phone

*

ERROR at line 1:

ORA-01418: specified index does not exist

--再次drop 索引时,提示索引已经不存在,说明已经在删除约束的同时,把索引删掉了。

SYS@anqing2(rac2)> selectconstraint_name,constraint_type,table_name,index_owner,index_name fromuser_constraints where table_name = 'UT';

no rows selected

SYS@anqing2(rac2)> selectindex_name,index_type,uniqueness,generated from user_indexes wheretable_name='UT';

no rows selected

结论:

当约束列上没有索引时,在创建unique constraint 时,oracle 会自动创建unique index,并且该索引不能删除,当删除unique constraint 时,unique index 会自动删除。

2.2 测试unique constraint 和non-unique index

--现在字段phone上创建B-Tree索引

SYS@anqing2(rac2)> create indexidx_ut_phone on ut(phone);

Index created.

--查看索引

SYS@anqing2(rac2)> selectindex_name,index_type,uniqueness,generated from user_indexes wheretable_name='UT';

INDEX_NAME INDEX_TYPE UNIQUENES GENERATED

------------- ------------- -------------------

IDX_UT_PHONE NORMALNONUNIQUE N

--创建unique constraint

SYS@anqing2(rac2)> alter table ut add constraint uc_phoneunique(phone);

Table altered.

--查看约束和索引信息

SYS@anqing2(rac2)> selectconstraint_name,constraint_type,table_name,index_owner,index_name fromuser_constraints where table_name = 'UT';

CONSTRAINT_NAME C TABLE_NAME INDEX_OWNERINDEX_NAME

--------------- - -------------------------- -------------

UC_PHONE U UT SYSIDX_UT_PHONE

--这里重用了已经存在的索引

SYS@anqing2(rac2)> selectindex_name,index_type,uniqueness,generated from user_indexes wheretable_name='UT';

INDEX_NAME INDEX_TYPE UNIQUENES GENERATED

------------- ------------- -------------------

IDX_UT_PHONE NORMALNONUNIQUE N

--删除索引

SYS@anqing2(rac2)> drop indexIDX_UT_PHONE;

drop index IDX_UT_PHONE

*

ERROR at line 1:

ORA-02429: cannot drop index used forenforcement of unique/primary key

--这个提示和之前的一样,我们先删除约束,在来查看

SYS@anqing2(rac2)> alter table ut dropconstraint uc_phone;

Table altered.

SYS@anqing2(rac2)> select constraint_name,constraint_type,table_name,index_owner,index_namefrom user_constraints where table_name = 'UT';

no rows selected

--这里约束已经删除掉了。

SYS@anqing2(rac2)> selectindex_name,index_type,uniqueness,generated from user_indexes wheretable_name='UT';

INDEX_NAME INDEX_TYPE UNIQUENES GENERATED

------------- ------------- -------------------

IDX_UT_PHONE NORMALNONUNIQUE N

--但是我们的索引并在删除约束时删除掉

--在手工删除索引,成功

SYS@anqing2(rac2)> drop indexIDX_UT_PHONE;

Index dropped.

SYS@anqing2(rac2)> selectindex_name,index_type,uniqueness,generated from user_indexes wheretable_name='UT';

no rows selected

--重新把约束和索引加上,然后一次删除

SYS@anqing2(rac2)> create indexidx_ut_phone on ut(phone);

Index created.

SYS@anqing2(rac2)> alter table ut addconstraint uc_phone unique(phone);

Table altered.

SYS@anqing2(rac2)> selectconstraint_name,constraint_type,table_name,index_owner,index_name fromuser_constraints where table_name = 'UT';

CONSTRAINT_NAME C TABLE_NAME INDEX_OWNER INDEX_NAME

--------------- - -------------------------- -------------

UC_PHONE U UT SYS IDX_UT_PHONE

SYS@anqing2(rac2)> selectindex_name,index_type,uniqueness,generated from user_indexes wheretable_name='UT';

INDEX_NAME INDEX_TYPE UNIQUENES GENERATED

------------- ------------- -------------------

IDX_UT_PHONE NORMALNONUNIQUE N

SYS@anqing2(rac2)>alter table ut drop constraint uc_phone drop index;

Table altered.

SYS@anqing2(rac2)> selectconstraint_name,constraint_type,table_name,index_owner,index_name fromuser_constraints where table_name = 'UT';

no rows selected

SYS@anqing2(rac2)> selectindex_name,index_type,uniqueness,generated from user_indexes wheretable_name='UT';

no rows selected

--索引和约束一次删除

小结:

当我们的列上有索引时,在创建unique constraint时,Oracle 会重用之前的索引,并且不会改变索引的类型,在第一个测试里,Oracle 自动创建的索引是unique index。

当我们删除约束时,关联的索引不会自动删除。 这个问题的MOS 上有说明。 参考MOS [ID309821.1]。

我们可以分两步,先删除约束,在删除索引。 MOS 提供了方法,就是在删除约束时,加上drop index,这样就能一次搞定。

SQL>altertable ut drop constraint uc_phone drop index;

-------------------------------------------------------------------------------------------------------

分享到:
评论

相关推荐

    oracle约束和索引笔记

    - **唯一索引(Unique Index)**: 确保索引键的唯一性,与唯一约束相似,但不强制非空。 - **分区索引(Partitioned Index)**: 将大型表的索引分割成更小、更易管理的部分,提高大规模数据的查询性能。 - **复合...

    oracle创建表创建唯一索引

    在Oracle数据库管理系统中,创建表和唯一索引是数据库设计中的关键步骤,它们对于数据的组织、查询效率和数据完整性至关重要。以下将详细介绍如何创建学员信息表,创建唯一索引,以及如何修改表来添加主键和检查约束...

    oracle笔记 (创建、更改、删除[table,constraint,index,view,sequence])

    有多种类型的约束,如 PRIMARY KEY(主键约束,唯一且非空)、FOREIGN KEY(外键约束,关联到另一表的主键)、UNIQUE(唯一约束,不允许重复值)和NOT NULL(非空约束,不允许存储NULL值)。例如: ```sql ALTER ...

    Oracle数据库表建立字段唯一性的方法

    - **定义**:唯一索引是在表的特定列上创建的索引,其作用与唯一约束相似,但它是通过索引实现的,而不是通过表级约束。唯一索引可以提高查询性能,并自动阻止任何重复值的插入。 - **语法**: ```sql CREATE ...

    oracle约束详解

    使用`USING INDEX`关键字可以为唯一性约束指定索引存储空间: ```sql ALTER TABLE Employees ADD CONSTRAINT emp_uk UNIQUE (EName, Phone) USING INDEX TABLESPACE indx; ``` #### 外键约束(Foreign Key) 外键...

    如何在oracle中查询所有用户表的表名、主键名称、索引、外键等

    与查询主键信息类似,这里通过 `constraint_type = 'U'` 来筛选出唯一性约束。这可以帮助我们了解哪些列是具有唯一性的,这对于理解表结构至关重要。 ### 4. 查询所有用户表的外键信息 #### SQL 语句: ```sql -- ...

    ORACLE的索引和约束详解.pdf

    **唯一约束(Unique Constraints)** 唯一约束保证字段或一组字段的值的唯一性,但允许有NULL值。可以在字段级或表级定义: ```sql CREATE TABLE employees ( empno NUMBER(5), ename VARCHAR2(15), phone ...

    oracle电子文档:数据库约束.rar

    2. **约束与索引**:主键和唯一约束通常自动创建索引,这些索引有助于提高查询速度。然而,过多的索引可能会占用大量磁盘空间并影响写操作性能。 3. **表分区与约束**:在大型表上使用分区技术时,约束处理也需考虑...

    Oracle约束基本语法 修改表结构

    2. **UNIQUE约束**:确保字段中的值是唯一的,但允许有NULL值。 3. **PRIMARY KEY约束**:定义表的主键,它是一个或一组唯一且非空的字段,标识表中的每一行。 4. **FOREIGN KEY约束**:建立表之间的参照完整性,一...

    Oracle字段约束.docx

    其次,唯一性约束(UNIQUE)与主键约束类似,但不强制非空。这意味着某个字段的值在表中必须是唯一的,但允许有NULL值。例如,在学生表中,可以为student_num字段添加唯一性约束: ```sql ALTER TABLE student ADD ...

    constraint约束.docx

    与主键不同,主键可以作为表的索引,而唯一约束不一定。 创建时添加: ```sql create table tbs1(id number unique, name varchar(9)); ``` 后期添加: ```sql alter table tbs1 add unique(col_name); ```...

    Oracle数据库的完整性约束和序列规则详解[收集].pdf

    语法如下:CONSTRAINT constraint_name (column) UNIQUE USING INDEX TABLESPACE (tablespace_name) STORAGE (stored clause) 唯一性约束由一个B-tree索引增强,所以可以在USING子串中为索引使用特殊特征,比如表...

    Oracle管理索引、权限和角色复习过程.pdf

    本文将对 Oracle 管理索引、权限和角色进行详细的介绍,包括数据完整性、约束、索引、权限和角色等方面的知识点。 一、数据完整性 数据完整性是指数据库中的数据遵从一定的商业和逻辑规则,以确保数据的正确性和...

    Oracle管理索引、权限和角色.doc

    综上所述,Oracle数据库的索引管理、权限和角色控制以及数据完整性约束是数据库管理员日常工作中不可或缺的部分,它们共同确保了数据的准确性和系统的安全性。了解和熟练掌握这些概念和操作,对于优化数据库性能和...

    oracle 学习心得与总结

    - **唯一约束(UNIQUE)**:保证列中的值唯一,但允许有NULL值。 - **检查约束(CHECK)**:限制列中的值必须满足特定条件。 - **外键约束(FOREIGN KEY)**:建立表之间的引用完整性,确保参照的列在另一张表中...

    oracle索引

    5. **创建与约束相关的索引**: ```sql ALTER TABLE table_name ADD CONSTRAINT constraint_name PRIMARY KEY (column_name) USING INDEX TABLESPACE tablespace_name; ``` 6. **创建局部分区索引**: - 基础...

    ORACLE和SQL语法区别归纳

    - Oracle的检查约束(CHECK CONSTRAINT)、唯一约束(UNIQUE CONSTRAINT)和外键约束(FOREIGN KEY CONSTRAINT)提供了更严格的数据完整性保证。 8. **触发器和序列** - Oracle的触发器(TRIGGER)允许在特定事件...

Global site tag (gtag.js) - Google Analytics