主键、唯一键与唯一索引的区别

一般,我们看到术语“索引”和“键”交换使用,但实际上这两个是不同的。索引是存储在数据库中的一个物理结构,键纯粹是一个逻辑概念。键代表创建来实施业务规则的完整性约束。索引和键的混淆通常是由于数据库使用索引来实施完整性约束。

接下来我们看看数据库中的主键约束、唯一键约束和唯一索引的区别。

SQL> select * from v$version;

BANNER

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

Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production

PL/SQL Release 11.2.0.1.0 - Production

CORE    11.2.0.1.0      Production

TNS for Linux: Version 11.2.0.1.0 - Production

NLSRTL Version 11.2.0.1.0 - Production

SQL> create table test (

2  id int,

3  name varchar2(20),

4  constraint pk_test primary key(id))

5  tablespace users;

Table created.

SQL> select constraint_name, constraint_type from user_constraints;

CONSTRAINT_NAME                C

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

PK_TEST                        P

在test表中,我们指定了ID列作为主键,Oracle数据库会自动创建一个同名的唯一索引:

SQL> select index_name, index_type, uniqueness, tablespace_name

2  from user_indexes

3  where table_owner=‘SCOTT‘

4  and table_name = ‘TEST‘;

INDEX_NAME           INDEX_TYPE           UNIQUENES TABLESPACE_NAME

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

PK_TEST              NORMAL               UNIQUE    USERS

此时,如果我们再试图在ID列上创建一个唯一索引,Oracle会报错,因为该列上已经存在一个唯一索引:

SQL> create unique index idx_test_uk on test(id);

create unique index idx_test_uk on test(id)

*

ERROR at line 1:

ORA-01408: such column list already indexed

即使创建非唯一索引也不行:

SQL> create index idx_test_id on test(id);

create index idx_test_id on test(id)

*

ERROR at line 1:

ORA-01408: such column list already indexed

那么唯一键约束的情况是怎样的呢?

SQL> drop table test purge;

Table dropped.

SQL> create table test(

2  id int,

3  name varchar2(20),

4  constraint uk_test unique(id));

Table created.

SQL> select constraint_name, constraint_type from user_constraints;

CONSTRAINT_NAME                C

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

UK_TEST                        U

查看此时的索引情况:

SQL> select index_name, index_type, uniqueness, tablespace_name

2  from user_indexes

3  where table_owner=‘SCOTT‘

4  and table_name = ‘TEST‘;

INDEX_NAME           INDEX_TYPE           UNIQUENES TABLESPACE_NAME

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

UK_TEST              NORMAL               UNIQUE    USERS

Oracle同样自动创建了一个同名的唯一索引,而且也不允许再在此列上创建唯一索引或非唯一索引。

我们知道,主键约束要求列值非空(NOT NULL),那么唯一键约束是否也要求非空呢?

SQL> insert into test values(1, ‘Sally‘);

1 row created.

SQL> insert into test values(null, ‘Tony‘);

1 row created.

SQL> insert into test values(null, ‘Jack‘);

1 row created.

SQL> select * from test;

ID NAME

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

1 Sally

Tony

Jack

从实验结果来看,唯一键约束并没有非空要求。

接下来我们看看唯一索引对列值的非空要求有什么不同。

SQL> drop table test purge;

Table dropped.

SQL> create table test(

2  id int,

3  name varchar2(20));

Table created.

SQL> create unique index idx_test_id on test (id);

Index created.

SQL> insert into test values(1, ‘Sally‘);

1 row created.

SQL> insert into test values(null, ‘Tony‘);

1 row created.

SQL> insert into test values(null, ‘Jack‘);

1 row created.

SQL> select * from test;

ID NAME

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

1 Sally

Tony

Jack

通过实验,我们看出唯一索引与唯一键约束一样对列值非空不做要求。

如果我们让主键约束或者唯一键约束失效,Oracle自动创建的唯一索引是否会受到影响?

SQL> drop table test purge;

Table dropped.

SQL> create table test(

2  id int,

3  name varchar2(20),

4  constraint uk_test unique(id));

Table created.

SQL> select index_name, index_type, uniqueness from user_indexes;

INDEX_NAME                     INDEX_TYPE                  UNIQUENES

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

UK_TEST                        NORMAL                      UNIQUE

SQL> alter table test disable constraint uk_test;

Table altered.

SQL> select index_name, index_type, uniqueness from user_indexes;

no rows selected

当主键约束或者唯一键约束失效时,Oracle会删除隐式创建的唯一索引。

如果我们先创建唯一索引,再创建主键或者唯一键约束,情况又会怎样呢?

SQL> drop table test purge;

Table dropped.

SQL> create table test(

2  id int,

3  name varchar2(20));

Table created.

SQL> create unique index idx_test_id on test (id);

Index created.

SQL> select index_name, index_type, uniqueness

2  from user_indexes

3  where table_owner = ‘SCOTT‘

4  and table_name = ‘TEST‘;

-- 何问起 hovertree.com

INDEX_NAME                     INDEX_TYPE                  UNIQUENES

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

IDX_TEST_ID                    NORMAL                      UNIQUE

SQL> alter table test add constraint uk_test unique (id);

Table altered.

SQL> select index_name, index_type, uniqueness

2  from user_indexes

3  where table_owner = ‘SCOTT‘

4  and table_name = ‘TEST‘;

INDEX_NAME                     INDEX_TYPE                  UNIQUENES

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

IDX_TEST_ID                    NORMAL                      UNIQUE

SQL> select constraint_name, constraint_type

2  from user_constraints

3  where table_name = ‘TEST‘;

CONSTRAINT_NAME                C

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

UK_TEST                        U

SQL> alter table test disable constraint uk_test;

Table altered.

SQL> select constraint_name, constraint_type, status

2  from user_constraints

3  where table_name = ‘TEST‘;

CONSTRAINT_NAME                C STATUS

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

UK_TEST                        U DISABLED

SQL> select index_name, index_type, uniqueness, status

2  from user_indexes

3  where table_owner = ‘SCOTT‘

4  and table_name = ‘TEST‘;

INDEX_NAME                     INDEX_TYPE                  UNIQUENES STATUS

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

IDX_TEST_ID                    NORMAL                      UNIQUE    VALID

实验结果表明,先创建的唯一索引不受约束失效的影响。

总结如下:

(1)主键约束和唯一键约束均会隐式创建同名的唯一索引,当主键约束或者唯一键约束失效时,隐式创建的唯一索引会被删除;

(2)主键约束要求列值非空,而唯一键约束和唯一索引不要求列值非空;

(3)相同字段序列不允许重复创建索引

http://www.cnblogs.com/roucheng/

时间: 2025-01-05 06:08:51

主键、唯一键与唯一索引的区别的相关文章

主键唯一键重复插入解决方法

[MySQL日记]主键唯一键重复插入解决方法 我们插入数据的时候,有可能碰到重复数据插入的问题,但是这些数据又是不被允许有重复值: ? 1 CREATE TABLE stuInfo ( id INT NOT NULL COMMENT '序号', name VARCHAR(20) NOT NULL DEFAULT '' COMMENT '姓名', age INT NOT NULL DEFAULT 0 COMMENT '年龄', PRIMARY KEY (id), UNIQUE KEY uniq_n

主键、唯一键、唯一索引的使用

主键只能用一个,不能为NULL,唯一(可以多列作为复合主键,当所有设置为复合主键的列都相同是视为唯一,多对多的表中常用) 唯一键,也称(唯一约束),和主键的区别是可以为有多个唯一键并且值可以为NULL,但NULL也不能重复,也就是说只能有一行的值为NULL.它会隐式的创建唯一索引. alter table 表名 add constraint 约束名 unique(列名) 唯一索引,几乎和唯一键一样,但可以添加过滤器来允许重复某些值 CREATE UNIQUE INDEX 索引名 ON 表名 (列

[MySQL日记]主键唯一键重复插入解决方法

我们插入数据的时候,有可能碰到重复数据插入的问题,但是这些数据又是不被允许有重复值: CREATE TABLE stuInfo ( id INT NOT NULL COMMENT '序号', name VARCHAR(20) NOT NULL DEFAULT '' COMMENT '姓名', age INT NOT NULL DEFAULT 0 COMMENT '年龄', PRIMARY KEY (id), UNIQUE KEY uniq_name(name) ) ENGINE=InnoDB D

MySQL 处理插入过程中的主键唯一键重复值办法

200 ? "200px" : this.width)!important;} --> 介绍 本篇文章主要介绍在插入数据到表中遇到键重复避免插入重复值的处理方法,主要涉及到IGNORE,ON DUPLICATE KEY UPDATE,REPLACE:接下来就分别看看这三种方式的处理办法. IGNORE 使用ignore当插入的值遇到主键(PRIMARY KEY)或者唯一键(UNIQUE KEY)重复时自动忽略重复的记录行,不影响后面的记录行的插入, 创建测试表 CREATE TA

主键约束,唯一性约束,唯一性索引

1)主键列:比如我们在表A中指定ID为主键,Oracle数据库会自动创建一个同名的唯一索引 可以通过 select constraint_name,constraint_type from user_indexes ui where ui.table_name='A'来查看主键上的唯一索引,如果此时我们在给ID列去创建唯一性索引或者非唯一性索引的话,都会报错,当然指定主键之后自动也会生成主键约束,主键就是一种约束 (2)非主键列:我们在非主键列上创建一个唯一性约束,Oracle同样自动创建了一个

主键、自增主键、主键索引、唯一索引概念区别与性能区别

概念区别: 主键:指字段唯一不为空值的列. 主键索引:指的就是主键,主键没有明确的概念定义,主键既是约束,也是索引,主键是索引的一种,是唯一索引的特殊类型.创建主键的时候,数据库默认会为主键创建一个唯一索引. 自增主键:字段类型为数字.自增.并且是主键. 唯一索引:索引列的值必须唯一,但允许有空值.主键是唯一索引,这样说没错.但反火来说唯一索引也是主键就错误了,因为唯一索引允许空值,主键不允许有空值,所以不能说唯一索引也是主键. 性能区别: 通过测试,发现主键.自增主键.唯一索引的查询效率不一样

Oracle 数据库表中已有重复数据添加唯一键(唯一约束)

Oracle 数据库表中已有重复数据添加唯一键(唯一约束) 问题描述 以 demo 举例,模拟真实场景. 表 TEST_TABLE 有如下字段和数据:id 是主键,code 没有设置键和索引 ID CODE 1 code1 2 code2 3 code2 4 code2 5 code3 通过以上表中数据可以看出 code 是有重复数据的,此时如果我们直接添加唯一键,会报错. 通过 PL/SQL 可视化操作,或者通过 SQL 语句添加(ENABLE NOVALIDATE 的作用是约束新增数据但不会

【INDEX】Oracle中主键、唯一约束与唯一索引之区别

一.            概述一般在Oracle数据表中,我们都会看到主键,索引,也会看到唯一索引.唯一约束,那么他们有什么区别呢,下面通过一个小实验简单了解一下....http://www.shejiben.com/images/list/1379589/ http://www.shejiben.com/images/list/1379588/ http://www.shejiben.com/images/list/1379587/ http://www.shejiben.com/image

mysql 主键和唯一索引的区别

主键是一种约束,唯一索引是一种索引,两者在本质上是不同的. 主键创建后一定包含一个唯一性索引,唯一性索引并不一定就是主键. 唯一性索引列允许空值,而主键列不允许为空值. 主键列在创建时,已经默认为非空值 + 唯一索引了. 主键可以被其他表引用为外键,而唯一索引不能. 一个表最多只能创建一个主键,但可以创建多个唯一索引. 主键和唯一索引都可以有多列. 主键更适合那些不容易更改的唯一标识,如自动递增列.身份证号等. 在 RBO 模式下,主键的执行计划优先级要高于唯一索引. 两者可以提高查询的速度.