oracle 主键约束重名,主键及主键索引的关系及相互影响

主键的定义:列或多列的集合,用于唯一的标识表中的一行。一个表上只允许有一个主键。

我们在数据库中指定主键时,是通过主键约束来定义的。而创建主键约束时,又是需要有相应的索引来配合实现的。所以,本文的目的是总结创建主键约束时,采用不同的方法创建索引后,主键与该索引之间的关系及相互影响。

为配合本文的描述和测试,首先创建如下测试表:

create table test (id number,c1 varchar2(8));

一、 首先,我们来看最常用的创建主键约束及索引的方法:

alter table t1 add constraint pk_test_id primary key (id);

创建完成后,检查相应约束和索引视图中的内容:

SQL> select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     ENABLED

从上可见,我们已经创建了一个名为“PK_TEST_ID”的主键约束,其当前状态为有效状态。

SQL> select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

INDEX_NAME  UNIQUENESS     TABLE_NAME       STATUS

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

PK_TEST_ID  UNIQUE         TEST        VALID

从上可见,数据库同时自动为该主键约束创建了一个同名的唯一索引。

如果这时,我们将主键约束关闭或者删除,又会是什么情况呢?

SQL> alter table test disable constraint pk_test_id;

Table altered.

SQL> select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     DISABLED

SQL> select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

no rows selected

可见,当我们把主键约束关闭后,其同名的索引被自动删除了。

那如果我们不将主键约束关闭或者删除,而是将自动创建的同名索引关闭或删除,又会是什么情况呢?

SQL> alter table test enable constraint pk_test_id;

Table altered.

SQL> select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     ENABLED

SQL> select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

INDEX_NAME  UNIQUENESS     TABLE_NAME       STATUS

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

PK_TEST_ID  UNIQUE         TEST        VALID

首先,我们先恢复被关闭的主键约束,发现约束的状态已经恢复正常,而且同名的索引也被重建恢复了。现在我们将同名的索引关闭或删除。

SQL> alter index pk_test_id unusable;

Index altered.

SQL>  select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     ENABLED

SQL>  select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

INDEX_NAME  UNIQUENESS     TABLE_NAME       STATUS

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

PK_TEST_ID  UNIQUE         TEST        UNUSABLE

可见,当关闭索引后,除了索引的状态变为UNUSABLE外,主键的状态仍是正常状态。但若此时向表中插入数据,则会报错ORA-01502,如下所示:

SQL> insert into test values(1,'A');

insert into test values(1,'A')

*

ERROR at line 1:

ORA-01502: index 'U1.PK_TEST_ID' or partition of such index is in unusable state

如果这时我们删除索引,也会报错,提示有约束正在使用该索引,而不允许删除。

SQL> drop index pk_test_id;

drop index pk_test_id

*

ERROR at line 1:

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

从这两个现象,也证明主键约束是通过相应列上的索引来配合完成的。

至此,我们对第一种创建约束和索引的方法做一个总结:当主键约束的索引为创建主键约束时数据库自动创建的话,则关闭或删除约束,会自动删除相应的索引;而关闭相应的索引,虽然不会影响主键的状态,但此时向表中插入数据会报错(删除数据,以及对主键列的更新也会报错);而尝试删除该索引时,也会报错,而不允许删除该索引。

二、创建主键约束时,指定相应的索引的方法。

在创建主键约束时,我们也可以指定索引。方法如下:

SQL> drop table test purge;

Table dropped.

SQL> create table test (id number,c1 varchar2(8));

Table created.

SQL> alter table test add constraint pk_test_id primary key (id) using index (create index ind_test_id on test(id));

Table altered.

前两条SQL是重建测试环境,以避免前面测试的影响。最后一条SQL则是在ID列上指定了主键约束,同时指定创建了在该列上的非唯一索引。

我们通过相关约束和索引视图来查看一下:

SQL>  select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     ENABLED

SQL> select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

INDEX_NAME  UNIQUENESS     TABLE_NAME       STATUS

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

IND_TEST_ID NONUNIQUE      TEST        VALID

注意最后一条索引信息中索引的名称及唯一性与前面自动创建主键索引时的区别。这说明,非唯一索引,也可以用于配合完成主键约束。

如前测试,我们尝试把主键约束关闭或删除,看看是什么情况?

SQL> alter table test disable constraint pk_test_id;

Table altered.

SQL> select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     DISABLED

SQL>  select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

INDEX_NAME  UNIQUENESS     TABLE_NAME       STATUS

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

IND_TEST_ID NONUNIQUE      TEST        VALID

可见,除了相应的主键约束失效外,索引并没有受到影响。这与前边自动创建主键索引的情况是不同的。

接下来,我们再尝试关闭或删除相应的索引,是否会影响到相应的主键约束。

SQL> alter table test enable constraint pk_test_id;

Table altered.

SQL> alter index ind_test_id unusable;

Index altered.

SQL> select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     ENABLED

SQL> select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

INDEX_NAME  UNIQUENESS     TABLE_NAME       STATUS

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

IND_TEST_ID NONUNIQUE      TEST        UNUSABLE

可见,关闭索引并没有影响到相应主键约束的状态。但是否也如前面测试那样,不能插入数据呢?

SQL> insert into test values(1,'A');

insert into test values(1,'A')

*

ERROR at line 1:

ORA-01502: index 'U1.IND_TEST_ID' or partition of such index is in unusable state

果然,当主键约束所依赖的索引不可用时,数据的插入会报错(删除数据,以及对主键列的更新也会报错);而尝试删除该索引时,也会报错,而不允许删除该索引。这一点和前面测试的情况是相同的。

SQL> drop index ind_test_id;

drop index ind_test_id

*

ERROR at line 1:

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

三、创建主键约束时,已经在相应的主键列上存在索引时的情况

如果表TEST中已经存在了一个ID列上的索引,然后我再在ID列上创建主键约束,又是会是什么情况呢?

和前面一样,我们先重置测试环境。

SQL> drop table test purge;

Table dropped.

SQL> create table test (id number,c1 varchar2(8));

Table created.

然后,我们先创建一个ID列上的索引。

SQL> create index ind_test_id on test(id);

Index created.

接着,我们在ID列上创建主键约束。

SQL> alter table test add constraint pk_test_id primary key (id);

Table altered.

查看约束和索引的情况:

SQL> select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     ENABLED

SQL> select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

INDEX_NAME  UNIQUENESS     TABLE_NAME       STATUS

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

IND_TEST_ID NONUNIQUE      TEST        VALID

我们可以看到,这次创建主键约束时,自动选用了主键列上已经存在的索引,并没有像测试一中那样,去创建一个与主键同名的唯一索引。

我们继续测试关闭或删除约束,是否会影响索引?

SQL> alter table test disable constraint pk_test_id;

Table altered.

SQL> select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     DISABLED

SQL> select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

INDEX_NAME  UNIQUENESS     TABLE_NAME       STATUS

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

IND_TEST_ID NONUNIQUE      TEST        VALID

发现索引并不受影响。

继续测试关闭或删除索引对主键约束的影响。

SQL> alter table test enable constraint pk_test_id;

Table altered.

SQL>  alter index ind_test_id unusable;

Index altered.

SQL>  select constraint_name,constraint_type,table_name,status from user_constraints where table_name='TEST';

CONSTRAINT_NAME CO TABLE_NAME    STATUS

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

PK_TEST_ID  P  TEST     ENABLED

SQL> select index_name,uniqueness,table_name,status from user_indexes where table_name='TEST';

INDEX_NAME  UNIQUENESS     TABLE_NAME       STATUS

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

IND_TEST_ID NONUNIQUE      TEST        UNUSABLE

SQL>  insert into test values(1,'A');

insert into test values(1,'A')

*

ERROR at line 1:

ORA-01502: index 'U1.IND_TEST_ID' or partition of such index is in unusable state

SQL> drop index ind_test_id;

drop index ind_test_id

*

ERROR at line 1:

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

和此前的测试完全一样,将主键约束所依赖的索引关闭并不会影响主键约束的状态,但修改数据(包括增删改操作,其中修改特指对主键列的修改)是不被允许的。同样,删除索引,也是不被允许的。

至此,我们把前述三大测试总结一下:

1、对于创建主键约束时自动生成的同名唯一性索引的情况:

关闭或删除主键约束,相应的索引会被删除。

2、对于创建主键约束时,使用了非自动创建的索引的情况(在创建主键约束的SQL中指定创建索引或创建主键约束时,主键列上已有索引。):

关闭或删除主键约束,相应的索引并不会被删除,索引状态也不受影响。

3、在任何一种情况下,关闭主键约束所依赖的索引,都会引起数据插入、删除以及对主键列更新操作的报错。

4、在任何一种情况下,删除主键约束所依赖的索引,是不被允许的。

注意:

此外,有一个特例。即,当我们使用第二种方法,即在创建主键约束的同时,使用USING INDEX子句来创建了一个唯一索引时,比如:

alter table test add constraint pk_test_id primary key (id) using index (create unique index ind_test_id_uni on test(id));

如果这时,我关闭或删除主键约束,则该索引会被自动删除。而当我们恢复主键约束时,数据库会自动创建一个与主键同名的唯一性索引。另外,当我们关闭手工创建的唯一索引或删除它时,情况与前述的内容是一样的。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/22207394/viewspace-2080449/,如需转载,请注明出处,否则将追究法律责任。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/506863.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

oracle数据库密码复杂度查询,Oracle11g R2创建PASSWORD_VERIFY_FUNCTION对应密码复杂度验证函数步骤...

1、连接上Linux数据库服务器,切换到Oracle数据库用户桌面,打开终端,进入到环境变量$ORACLE_HOME目录Last login: Fri Dec 11 13:26:18 2015 from 192.168.1.100[rootLinux主机名 ~]# su - oracle[oracleLinux主机名 dbhome_1]$ cd $ORACLE_HO…

oracle加大内存对大表,在ORACLE里如果遇到特别大的表,可以使用分区的表来改变其应用程序的性能...

在ORACLE里如果遇到特别大的表,可以使用分区的表来改变其应用程序的性能。以system身份登陆数据库,查看 v$option视图,如果其中Partition为TRUE,则支持分区功能;否则不支持。Partition有基于范围、哈希、综和三种类型。…

php ci框架 模板引擎,详解CodeIgniter框架实现的整合Smarty引擎DEMO

CodeIgniter框架实现的整合Smarty引擎DEMO示例本文实例讲述了CodeIgniter框架实现的整合Smarty引擎。分享给大家供大家参考,具体如下:Smarty的模板机制很强大,一般情况下CI框架无需整合其他模板标签,因为PHP本身就是一种标签&…

padodb time.inc.php,怎样实现PHP中ADODB事务处理

这次给大家带来怎样实现PHP中ADODB事务处理,实现PHP中ADODB事务处理的注意事项有哪些,下面就是实战案例,一起来看一下。一、代码adodb.inc.php可从官方网站http://adodb.sourceforge.net/ 下载。或者点击此处本站下载。conn.php:&…

oracle清空无效数据,如何清除编译后留下的无效对象

在使用utlrp.sql编译后,查看发现还有一些invalid的object;请教这些invalid如何清除?多谢!SYSprimary>select object_name,object_type,owner from dba_objects where status not in (VALID);OBJECT_NAME OB…

linux隐藏特定进程,linux 隐藏进程

2、源码如下rootubuntu:/var/srt/libprocesshider# cat processhider.c#define _GNU_SOURCE#include #include #include #include #include /** Every process with this name will be excluded*/static const char* process_to_filter "srt";/** Get a directory n…

双用户windows linux系统,Windows与Linux合二为一?终于能在windows上运行Linux了!

原标题:Windows与Linux合二为一?终于能在windows上运行Linux了!目前在PC端操作系统市场份额中,微软旗下的windows系统占据超过50%的比例。作为微软旗下发布的产品之一,windows系统深受用户喜爱。从经典的XP和win7&…

linux的用户及权限管理,用户及权限管理

一、Linux用户、组的概念1.用户管理员:root,0其他用户:1-65535系统用户:1-499,守护进程获取资源进行权限分配普通用户:500,交互式登陆2.组管理员组:root,0其他用户:1-65535系统用户组:1-499普通用户组:500note:关于uid,gid的范围可以参考/etc/login.def3.Linux安全上下文进程所…

linux内存使用策略swap,Linux Swap使用分析

Linux操作系统性能分析主要包含磁盘IO、CPU、内存以及网络流量,而这里主要针对系统内存的使用进程情况做个分析。一、如何查看系统内存使用情况1、根据常用命令查看系统内存使用概况free -gtotal used free shared buffers cachedMem: …

linux从源码编译软件,linux软件源码的编译安装

软件包的组成:1二进制文件/bin,/sbin /usr/bin ,/usr/sbin /usr/local/bin /usr/local/sbin2库文件 /lib, /usr/lib /usr/local/lib3配置文件 /etc,/usr/local/etc4帮助文件 /usr/share/man usr/share/doc5头文件:/usr/include usr/local/includeA . bi…

linux对当前使用的分区分割,实例解说Linux中fdisk分区使用方法

一、fdisk 的介绍fdisk - Partition table manipulator for Linux ,译成中文的意思是磁盘分区表操作工具;本人译的不太好,也没有看中文文档;其实就是分区工具fdsik 能划分磁盘成为若干个区,同时也能为每个分区指定分区…

csky linux 编译内核,TQ2440的EmbedSky_hello模块编译内核问题及解决

已在内核代码中添加EmbedSky_hello驱动为例,进行内核编译时候出现了一下几个问题:1、在 /opt/EmbedSky/linux 2.6.30.4/drivers/char目录下修改“Kconfig”文件,添加如下内容:config EmbedSky_HELLOtristate "TQ2440/SKY2440…

Linux设置swap分区为128g,swap分区或文件的数量与大小限制

在Linux系统下,这个虚拟内存就被叫做swap。Linux swap分区是有限制的。在安装操作系统的时候,安装向导会提示用户需要创建多少的SWaP空间。通常情况下,SWaP比较合适的大小为物理内存的1-2倍。1. 早期的linux对虚拟内存的限制linux2.2以前的内…

linux设备树例程,iTOP-iMX6-设备树内核-实时时钟RTC以及Linux-c测试例程

当 Linux 开发者谈论一个实时时钟,他们通常指的是某种能记录墙上时间,并且有备用电池,以至于在系统关机的时候仍然可以工作的器件。Linux 有两个系列广泛兼容的用户空间 RTC 设备节点:• /dev/rtc : PC 机及兼容机系统…

linux有哪些实时同步工具,rsync文件同步工具常见模式有哪些?linux系统

互联网时代发展迅速,Linux运维技术的需求更多推进不少。市场对于Linux运维人才的需求也在逐渐加大。Linux行业崛起,在云计算大环境下,市场上对高级运维人员的需求将越来越大。文件同步工具rsync是运维工作中会遇到的命令,那么rsyn…

linux下rman自动备份,linux 下rman 自动备份

一、新建备份目录并授权:[oracleTAIXIN-HR ~]$ mkdir -p /home/oracle/app/hr_back (备份目录)mkdir -p /home/oracle/app/hr_back/archbackmkdir -p /home/oracle/app/hr_back/rmanscripts[oracleTAIXIN-HR ~]$ chmod 755 /home/oracle/app/hr_back (授权)chown…

linux jdk bin下载,Linux下安装jdk-6u45-linux-x64.bin

最近在学习linux下java开发,在搭环境的过程中发现网上很多配置都是错误的,现在写出来,供参考:从Oracle上下载jdk-6u45-linux-x64.bin1.下载文件:jdk-6u45-linux-x64.bin,将文件做成光盘挂载[rootlocalhost ~]mount /dev/cdrom /mn…

查看linux上redis的运行状态,Redis教程(七)使用info查看服务状态

一、Redis info命令介绍Redis info命令是Redis自带的一个用于查看服务状态的命令,这个命令类似于top一样可以查看redis服务的整个状态,并且分为了5大类:二、Redisinfo命令语法redis-cli -a redis_pass info #查看所有模块信息redis-cli -a re…

linux应用参数 冒号,Lua-面向对象中函数使用时冒号(:)和点(.)的区别

Lua-面向对象中函数使用时冒号(:)和点(.)的区别,我们先来看一段简单的代码:local Animal {}functionAnimal:Eat( food )print("Animal:Eat", self, food)endfunctionAnimal.Sleep( time )print("Animal.Sleep", self, time)endAnima…

linux tcp cork,在此用例中,TCP_CORK和TCP_NODELAY是否有显着差异?

在写完关于TCP_NODELAY和TCP_CORK的答案之后,我意识到我必须缺少对TCP_CORK的要点的了解,因为我尚不清楚100%为何Linux开发人员认为有必要引入一个新的TCP_CORK标志,而不是仅仅依靠应用程序在适当的时间设置或清除现有的TCP_NODEL…