Oracle主键约束、唯一键约束、唯一索引的区别
一般,我们看到术语“索引”和“键”交换使用,但实际上这两个是不同的。索引是存储在数据库中的一个物理结构,键纯粹是一个逻辑概念。键代表创建来实施业务规则的完整性约束。索引和键的混淆通常是由于数据库使用索引来实施完整性约束。
接下来我们看看数据库中的主键约束、唯一键约束和唯一索引的区别。
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';
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://langgufu.iteye.com/blog/1745915
Oracle主键约束、唯一键约束、唯一索引的区别的更多相关文章
- SQL Server的外键必须引用的是主键或者唯一键(转载)
问: In SQL Server , I got this error -> "There are no primary or candidate keys in the refere ...
- Sql Server中的游标最好只用于有主键或唯一键的表
游标cursor,我想大多数人都在sql server里面用过.当一个表数据量不太大的时候,游标还是可以用的,毕竟游标是循环一个表中每一行数据的最简便办法.但是如果你用一个游标去循环一个没有主键或唯一 ...
- powerdesigner设置主键为自增字段,设置非主键为唯一键并作为表的外键
转自:https://www.cnblogs.com/CoffeeHome/archive/2014/06/04/3767501.html 这里powerdesigner连接的数据库是以mysql为例 ...
- SQL Server的唯一键和唯一索引会将空值(NULL)也算作重复值
我们先在SQL Server数据库中,建立一张Students表: CREATE TABLE [dbo].[Students]( ,) NOT NULL, ) NULL, ) NULL, [Age] ...
- 视图view没有主键,但可以添加唯一索引
视图没有主键,但可以加上唯一索引 大致可以这样理解:视图是张虚拟的表.视图所对应的数据不进行实际的存储,数据库中只存储视图的定义,对视图的数据进行操作时,系统根据视图的定义去操作与视图相关联的基本表. ...
- SQL Server 数据库添加主键,唯一键,外键约束脚本
-- 声明使用数据库use 数据库;go -- 添加主键(primary key)约束-- 基本语法-- 判断主键约束是否存在,如果存在则删除,不存在则添加if exists(select * fro ...
- mysql中主键和唯一键的区别
区别项 primary key(主键) unique(唯一键约束) 唯一性 可以 可以 是否可以为空 不可以 可以 允许个数 只能有1个 允许多个 是否允许多列组合 允许 允许
- 生成主键ID,唯一键id,分布式ID生成器雪花算法代码实现
工具类: package com.ihrm.common.utils; import java.lang.management.ManagementFactory; import java.net. ...
- Oracle 数据库表中已有重复数据添加唯一键(唯一约束)
Oracle 数据库表中已有重复数据添加唯一键(唯一约束) 问题描述 以 demo 举例,模拟真实场景. 表 TEST_TABLE 有如下字段和数据:id 是主键,code 没有设置键和索引 ID C ...
随机推荐
- codility上的问题 (23)Chi 2012
这个题也比较有意思.意思是给定一个数组A,长度为M,里面都是正整数,代表每块地形的高度.现在要测试一种加农炮,给定一个炮弹的高度H, 如果存在最小的I,满足0 < I < M,满足A[I ...
- BZOJ1638: [Usaco2007 Mar]Cow Traffic 奶牛交通
1638: [Usaco2007 Mar]Cow Traffic 奶牛交通 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 571 Solved: 199 ...
- 【转】Android ListView长按事件触发点击事件
原文网址:http://blog.csdn.net/twlkyao/article/details/17301609 算法在实现ListView的onItemLongClickListener的时候, ...
- 利用linux信号机制调试段错误(Segment fault)
在实际开发过程中,大家可能会遇到段错误的问题,虽然是个老问题,但是其带来的隐患是极大的,只要出现一次,程序立即崩溃中止.如果程序运行在PC中,segment fault的调试相对比较方便,因为可以通过 ...
- wikioi1082【线段树练习 3 】
题目描述 Description 给你N个数,有两种操作: 1:给区间[a,b]的所有数增加X 2:询问区间[a,b]的数的和. 输入描述 Input Description 第一行一个正整数n,接下 ...
- linux下 tags相关
在vim中配置好了YouCompleteMe插件,发现把光标移动到函数名下再按ctrl+],并不能跳转到该函数的定义处.解决办法: 1.先查看有没有安装ctags,运行ctags –version查看 ...
- linux内核--中断和中断处理(一)
让硬件在需要的时候再向内核发出信号.这就是中断机制,先讨论中断,进而讨论内核如何使用所谓的中断处理函数处理对应的中断. 一.中断 1)中断 中断使得硬件得以发出通知给处理器.例如, ...
- WPF - 使用WPF创建图表
最近有点想把自己的项目里面加入图表,让程序看起来高大上起来.没办法,很大一部分要靠包装,使用好图表,让程序图文并茂,就是包装的一个好法子.. WPF toolkit里面有常见的图表控件 如何使用: h ...
- PHP设计模式笔记九:装饰器模式 -- Rango韩老师 http://www.imooc.com/learn/236
装饰器模式(Decorator) 概述 1.装饰器模式可以动态地添加修改类的功能 2.一个类提供了一项功能,如果要在修改并添加额外的功能,传统的编程模式,需要写一个子类继承它,并重新实现类的方法 3. ...
- C# 初识Ref和Out
首先:两者都是按地址传递的,使用后都将改变原来参数的数值. 其次:ref可以把参数的数值传递进函数,但是out是要把参数清空,就是说你无法把一个数值从out传递进去的,out进去后,参数的数值为空,所 ...