Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >主键约束索引的奇葩现象

主键约束索引的奇葩现象

作者头像
bisal
发布于 2021-09-06 07:09:11
发布于 2021-09-06 07:09:11
58200
代码可运行
举报
运行总次数:0
代码可运行

在Oracle数据库中,我们知道创建主键约束的时候,会自动创建唯一索引,靠着唯一索引,保证数据的唯一,删除主键约束时,会自动删除对应的唯一索引。但是最近碰到了个奇怪的问题,同事说测试环境中删除一张表的主键约束,发现约束删了,但唯一索引还在,难道有什么隐藏的问题?

Oracle11.2.0.4,创建测试表,然后创建主键,自动生成同名的索引,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQL> create table a (id number, name varchar2(30));
Table created.


SQL> alter table a add constraint pk_a primary key (id);
Table altered.


SQL> select constraint_name, constraint_type from user_constraints where table_name='A';
CONSTRAINT_NAME                C
------------------------------ -
PK_A                           P


SQL> select index_name, index_type from user_indexes where table_name='A';              
INDEX_NAME                     INDEX_TYPE
------------------------------ ---------------------------
PK_A                           NORMAL

直接删除约束,看到约束和索引确实都删除了,并未出现同事说的现象,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQL> alter table a drop constraint pk_a;
Table altered.


SQL> select constraint_name, constraint_type from user_constraints where table_name='A';
no rows selected


SQL> select index_name, index_type from user_indexes where table_name='A';
no rows selected

但是现象在这摆着的,有果必有因,看下MOS,是不是有类似的案例出现过,果然,370633.1这篇文章介绍的和我们碰到的很像,使用ALTER TABLE删除主键约束的时候不能删除隐含的索引,但是请注意,有个前提,就是待删除主键约束的表是通过导入执行的,并不是我们自己手工创建的,而且文章 明确说了如果表是自行创建的,不是导入进来的,删除主键约束的时候会连带删除主键索引,这个问题来自于一个未公布的bug,3894962,通过导入操 作,主键索引并未依赖于主键约束,因此当删除主键约束的时候,不会自动删除对应的主键(/唯一)索引,值得一提的是,9i中并无此现象,从10.1.0之 后的版本才出现此问题,解决方案就是删除索引,一种方式是drop constraint的时候带上drop index,一次性执行,另一种就是drop index删除索引,

我们验证下,从test用户导出表A,再imp导入到用户bisal,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[oracle@app ~]$ exp test/test file=/home/oracle/test.dmp tables=a
[oracle@app ~]$ imp bisal/bisal file=/home/oracle/test.dmp fromuser=test touser=bisal

此时删主键,约束确实删了,但是索引还在,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQL> alter table a drop constraint pk_a;
Table altered.


SQL> select constraint_name, constraint_type from user_constraints where table_name='A';
no rows selected


SQL> select index_name, index_type from user_indexes where table_name='A';
INDEX_NAME                     INDEX_TYPE
------------------------------ ---------------------------
PK_A                           NORMAL

此时两种方式,一是直接删索引,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQL> drop index pk_a;
Index dropped.


SQL> select index_name, index_type from user_indexes where table_name='A';
no rows selected

另一种就是删除主键约束的同时删除索引,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQL> alter table a drop constraint pk_a drop index;
Table altered.


SQL> select constraint_name, constraint_type from user_constraints where table_name='A';
no rows selected


SQL> select index_name, index_type from user_indexes where table_name='A';
no rows selected

说句题外话,以前很少用drop constraint ... drop index,他还是可以带来一定的便利性,例如某些开发组的规范,要求索引名称和约束名称具备固定的前缀,当创建主键时,可能选择先创建唯一索引,再创建主键,以便能自定义主键约束和索引的名称,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQL> create unique index idx_pk_a on a(id);
Index created.


SQL> alter table a add constraint pk_a primary key (id);
Table altered.


SQL> select index_name, index_type from user_indexes where table_name='A';              
INDEX_NAME                     INDEX_TYPE
------------------------------ ---------------------------
IDX_PK_A                       NORMAL


SQL> select constraint_name, constraint_type from user_constraints where table_name='A';
CONSTRAINT_NAME                C
------------------------------ -
PK_A                           P

此时删除主键,显而易见不能删除索引,因为名称不同,但使用drop constraint ... drop index,就可以做到了一次执行,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQL> alter table a drop constraint pk_a drop index;
Table altered.


SQL> select index_name, index_type from user_indexes where table_name='A';  
no rows selected


SQL> select constraint_name, constraint_type from user_constraints where table_name='A';
no rows selected

另一个骚操作,就是用drop primary key drop index,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQL> alter table a drop primary key drop index;
Table altered.


SQL> select constraint_name, constraint_type from user_constraints where table_name='A';
no rows selected


SQL> select index_name, index_type from user_indexes where table_name='A'; 
no rows selected

此外,文章中写的是import,并未提及是imp,还是用的impdp,因此,我们再测下数据泵的执行,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[oracle@app ~]$ expdp test/test directory=dir_test dumpfile=d_test.dmp tables=a
[oracle@app ~]$ impdp bisal/bisal directory=dir_test dumpfile=d_test.dmp fromuser=test touser=bisal

可知现象相同,因此针对这个bug,imp/exp和impdp/expdp都会涉及,

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
SQL> alter table a drop constraint pk_a;
Table altered.


SQL> select constraint_name, constraint_type from user_constraints where table_name='A';
no rows selected


SQL> select index_name, index_type from user_indexes where table_name='A';
INDEX_NAME                     INDEX_TYPE
------------------------------ ---------------------------
PK_A                           NORMAL

从这个案例,我们能体会到,无论什么技术,一种现象的产生,肯定有他的原因,结论固然重要,更重要的是探索结论的过程,以及为了支持结论需要了解的知识,正所谓知其然,更要知其所以然,就是这回事儿。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/10/19 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
巧用shell脚本生成快捷脚本(r2第12天)
在升级的过程中,可能需要准备一些额外的脚本,比如说做数据迁移的时候为了考虑性能,需要做如下的额外工作: 1.将部分表置为nologging 2.将部分index置为nologging 3.将部分foreign key constraint置为disable 4.将部分trigger 置为disable 在完成数据升级后,再置为logging,enable状态。 但是在准备脚本的过程中,总是为这些小脚本而头疼,可能在升级前临时增加了一些表或者取消了部分表。或者有了其他的变更,维护这些脚本就显得有些体力工作了。
jeanron100
2018/03/14
6240
Oracle 系统表大全
数据字典dict总是属于Oracle用户sys的。   1、用户:    select username from dba_users;   改口令    alter user spgroup identified by spgtest;   2、表空间:    select * from dba_data_files;    select * from dba_tablespaces;//表空间
一见
2018/08/07
5750
【Oracle】-【move】【索引】无数据的主键索引VALID还是UNUSABLE
SQL> desc t_PRIMARY;  Name                                      Null?    Type  -------------------
bisal
2019/01/29
6630
使用copy命令解决LONG类型的困扰(r2第24天)
在oracle的数据类型中,long类型算是一个比较另类的典型,早就不建议使用了,但是在数据字典里还是能看到long 类型的影子。 如果在一些工作中碰到long type就让人感觉long 类型像是被
jeanron100
2018/03/14
8970
Oracle创建主键的三种方式
从trace我们能看到,对T_PK_02加了share模式锁,指定nowait,先创建的约束,然后创建了唯一索引,
bisal
2021/03/20
1.7K0
很多人比较纠结的约束和索引的关系(r7笔记第75天)
最近有不少朋友公众号留言或者微信私信问我一个问题,出乎我的意料,问题竟然都是很相似的,所以我统一答复一下。 之前写了一篇文章 一个清理和查询都要兼顾的简单方案,看来很多朋友还是很关心这个分区索引中的唯一性约束是怎么建立的。我举个例子,当然内容中会贯穿说到你们的疑问,而且很可能你么对于约束和索引还是存在这一些误解。 首先我们创建一个测试表,为了简单起见,也没有注意很多的命名规则了。 create table test (id number,name varchar2(30)) partition by ran
jeanron100
2018/03/16
6890
执行truncate引发ORA-02266的问题分析
墨墨导读:将测试数据库的数据清空,其中涉及主子表的关系,执行truncate产生的ORA-02266问题处理过程。
数据和云
2019/07/17
9250
执行truncate引发ORA-02266的问题分析
Oracle 闪回特性(FLASHBACK DROP & RECYCLEBIN)
--==============================================
Leshami
2018/08/07
8320
使用dbms_metadata生成建表语句(r2笔记97天)
有时候在工作中,可以使用exp/imp得到表的创建语句。 如果想得到关于table,index,constraint的语句,可以考虑使用dbms_metadata来实现。 我们可以使用如下的脚本来得到建表语句,对应的索引语句,和ref_constraint语句。 建表语句就不多说了,关于索引的部分,过滤了主键和唯一性索引的部分,这些语句会和建表语句中的constraint有一定的冲突,而foreign key的语句在建表语句中也不建议使用,这样会对其他表产生依赖,可以考虑单独生成这部分的语句,最后执行。 所
jeanron100
2018/03/14
4880
存在外键关联的主表truncate如何做
我认为需要根据实际情况进行取舍,例如表不复杂,可以由应用实现,若表之间关联较多且复杂,那么交由数据库处理,至少保证不会错。
bisal
2019/01/30
8630
主键、唯一键与唯一索引的区别
一般,我们看到术语“索引”和“键”交换使用,但实际上这两个是不同的。索引是存储在数据库中的一个物理结构,键纯粹是一个逻辑概念。键代表创建来实施业务规则的完整性约束。索引和键的混淆通常是由于数据库使用索引来实施完整性约束。
全栈程序员站长
2022/07/15
1.4K0
《数据库索引设计优化》读书笔记(七)
第13章 数据库索引选项 练习 13.1 调查你当前使用的DBMS版本关于索引的限制和高级选项。 .索引行压缩与异常情况 MySQL支持 Oracle支持 MySQL使用NULL值实现索引行压缩。但不推荐在实际中使用NULL来代替一个特定的值,因为从长远来看,这可能会导致应用系统错误。
用户1148526
2022/05/07
2090
《数据库索引设计优化》读书笔记(七)
not null constraint和check constriant的问题及分析(64天)
oracle的constraint有6类,如下。 但是基于列的constraint主要有 type 为C,P,R,U 接触比较多的。 今天来和大家讨论check constraint和not null constraint,它们的constraint type都为C,但是实际应用中还是有很大的差别。 Type CodeType DescriptionActs On LevelCCheck on a tableColumnORead Only on a viewObjectPPrimary KeyObje
jeanron100
2018/03/13
1.3K0
分区索引学习笔记 (77天)
续接上次的分区表学习笔记,对分区索引进行了总结。 --index maintance SQL> select index_name,table_name from user_indexes where table_name='RANGE_PART'; no rows selected --create one global index SQL> create index glb_range_part on range_part(a,b) 2 global partition by range(a)
jeanron100
2018/03/14
6140
表中已存重复数据的情况,如何增加唯一性约束?
这周某系统上线,有一个需求就是,为一张表修改唯一性约束,原因就是之前发现,由于唯一性约束设置不当,导致业务处理出现异常。
bisal
2019/01/30
2.2K0
总结Oracle删除表空间遇到的问题
删除表空间语句:`DROP TABLESPACE SAC INCLUDING CONTENTS AND DATAFILES;` 根据MOS文档: How To Resolve ORA-29857 During a Drop Tablespace although No Domain Index exists in This Tablespace (文档 ID 1610456.1) 对于ORA-29857这个错误,文档说的很清楚:
Alfred Zhao
2022/05/06
1K0
主键和唯一约束的索引肯定唯一?
这两天在开发过程中,有个需求,就是找出某个schema的所有主键索引和唯一约束索引的名称,逻辑中用到了dba_indexes,其中存在一个字段叫UNIQUENESS,官方文档解释是说该字段会标记索引是唯一的(UNIQUE)还是非唯一的(NONUNIQUE),能不能这样理解,对主键索引和唯一约束索引来说,这个字段应该是UNIQUE?
bisal
2021/09/06
1.3K0
主键和唯一约束的索引肯定唯一?
创建主键的三种方式对指定索引表空间操作的纠正
《Oracle创建主键的三种方式》曾说了创建主键的三种方式,对第三种方式的作用,提到了这个原因,
bisal
2021/09/06
4260
创建主键的三种方式对指定索引表空间操作的纠正
解锁不可见索引新特性,处理ORA-01555故障
何国亮 云和恩墨交付部技术顾问,获得 Oracle 11g OCM 认证。有超过 6 年超大型数据库专业服务经验,曾为通信运营商、银行、保险、政府、制造业等行业客户的业务关键型系统提供了运维、升级、性能优化、项目实施与管理、容灾建设等咨询与技术实施服务。在超大规模数据库(VLDB)、业务连续性与高可用、升级迁移、性能优化与管理等方面有丰富的实战经验。
数据和云
2018/08/09
6020
解锁不可见索引新特性,处理ORA-01555故障
oracle删除主键索引的sql语句_oracle主键索引和普通索引
相信不少人遇到过ORA-02429: cannot drop index used for enforcement of unique /primary key 这个错误,对应的中文提示“ORA-02429: 无法删除用于强制唯一/主键的索引”,其实从错误提示信息已经很明显了。下面还是用一个简单的例子述说一下该错误的来龙去脉。
全栈程序员站长
2022/10/03
3.9K0
推荐阅读
相关推荐
巧用shell脚本生成快捷脚本(r2第12天)
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文