删除主键,唯一约束,什么时候会自动删除列上的索引?

你可能经常会有这样的顾虑,在删除唯一约束或者主键约束的时候,附带的索引会不会被删除掉?
现在的团队有一个规范,但凡是增加主键,都需要先手工创建索引,再增加主键。给出的原因是:这样删除主键的时候,索引就不会被删除掉了。
Oracle是怎么知道这个索引是手工创建的,还是Oracle自动(递归)创建的?如果Oracle可以区别开这两者,貌似就有一个可以猜测的答案:
Oracle在删除主键或者唯一约束的时候,对于自动创建的索引会递归的删除掉,对于手工创建的索引会保留。(这并不是最终的结论,最终的结论在文章的最后)。

其实Oracle可以区别开这两者,查看sql.bsq(一般位于$ORACLE_HOME/RDBMS/ADMIN下)文件,里面有ind$视图的创建语句:

create table ind$                                             /* index table */
( obj#          number not null,                            /* object number */
  /* DO NOT CREATE INDEX ON DATAOBJ#  AS IT WILL BE UPDATED IN A SPACE
   * TRANSACTION DURING TRUNCATE */
  dataobj#      number,                          /* data layer object number */
  ts#           number not null,                        /* tablespace number */
  file#         number not null,               /* segment header file number */
  block#        number not null,              /* segment header block number */
  bo#           number not null,              /* object number of base table */
  indmethod#    number not null,    /* object # for cooperative index method */
  cols          number not null,                        /* number of columns */
  pctfree$      number not null, /* minimum free space percentage in a block */
  initrans      number not null,            /* initial number of transaction */
  maxtrans      number not null,            /* maximum number of transaction */
  pctthres$     number,           /* iot overflow threshold, null if not iot */
  type#         number not null,              /* what kind of index is this? */
                                                               /* normal : 1 */
                                                               /* bitmap : 2 */
                                                              /* cluster : 3 */
                                                            /* iot - top : 4 */
                                                         /* iot - nested : 5 */
                                                            /* secondary : 6 */
                                                                 /* ansi : 7 */
                                                                  /* lob : 8 */
                                             /* cooperative index method : 9 */
  flags         number not null,      
                /* mutable flags: anything permanent should go into property */
                                                    /* unusable (dls) : 0x01 */
                                                    /* analyzed       : 0x02 */
                                                    /* no logging     : 0x04 */
                                    /* index is currently being built : 0x08 */
                                     /* index creation was incomplete : 0x10 */
                                           /* key compression enabled : 0x20 */
                                              /* user-specified stats : 0x40 */
                                            /* secondary index on IOT : 0x80 */
                                      /* index is being online built : 0x100 */
                                    /* index is being online rebuilt : 0x200 */
                                                /* index is disabled : 0x400 */
                                                     /* global stats : 0x800 */
                                            /* fake index(internal) : 0x1000 */
                                       /* index on UROWID column(s) : 0x2000 */
                                            /* index with large key : 0x4000 */
                             /* move partitioned rows in base table : 0x8000 */
                                 /* index usage monitoring enabled : 0x10000 */
                      /* 4 bits reserved for bitmap index version : 0x1E0000 */
  property      number not null,    /* immutable flags for life of the index */
                                                            /* unique : 0x01 */
                                                       /* partitioned : 0x02 */
                                                           /* reverse : 0x04 */
                                                        /* compressed : 0x08 */
                                                        /* functional : 0x10 */
                                              /* temporary table index: 0x20 */
                             /* session-specific temporary table index: 0x40 */
                                              /* index on embedded adt: 0x80 */
                         /* user said to check max length at runtime: 0x0100 */
                                              /* domain index on IOT: 0x0200 */
                                                      /* join index : 0x0400 */
                /* functional index expr contains a PL/SQL function : 0x0800 */
                           /* The index was created by a constraint : 0x1000 */
                              /* The index was created by create MV : 0x2000 */


property列是我们需要关注的。当值为0x1000的时候,就是Oracle自动创建的索引。换算成10进制就是4096。这个property的值有个特点,它的各个可以取的值是按照2的倍数增长的。
property的值可以是多个值的和,比如这个索引是唯一的,且是自动创建,那么这个property的值就是0x01+0x1000 转换为10进制就是1+4096=4097

/* The index was created by a constraint : 0x1000 */
property为0x10000的时候,代表这个索引是ORACLE自动(递归)创建的,非手工创建的。
下面我们做几个实验,来验证什么时候Oracle会递归删除掉约束上的索引:

1)建表的同时,指定主键。
create table wxh_tbd(id number ,primary key(id));
找出对应索引的object_id(略)
select PROPERTY from ind$  where OBJ#='193613';

  PROPERTY
----------
      4097
4097代表4096+1,转化为16进制就是:0x1000+0x01 代表了 oracle自动创建了索引而且是唯一索引

这种情况下如果你:
alter table wxh_tbd drop primary key;

拿IND查看索引
@ind
NO ROWS

发现索引也没了。

2)手工创建索引(唯一索引)
create table wxh_tbd(id number);
create unique index ttt on wxh_tbd(id);
alter table wxh_tbd add constraint pk_o primary key(id);

select PROPERTY from ind$  where OBJ#='193616';
  PROPERTY
----------
         1
1代表是个唯一索引。
这种情况下如果你:
alter table wxh_tbd drop primary key;


@ind

TABLE_NAME                INDEX_NAME                     COLUMN_NAME          TABLESPACE_NAME INDEX_TYPE
------------------------- ------------------------------ -------------------- --------------- ----------------------
WXH_TBD                   PK_O                           ID                   SYSTEM          NORMAL

发现索引还在,因为这个索引不是ORACLE自动创建的。

3)手工创建索引(非唯一索引)
这种情况我不列出来了,由于也是手工创建的,所以,删除约束后,索引还在。


4)创建表的同时,指定主键,但是语法上特殊了一点点。创建了一个唯一索引
create table wxh_tbd(id number ,primary key (id) using index (create unique index ttt on wxh_tbd(id)));
select PROPERTY from ind$  where OBJ#='193616';

  PROPERTY
----------
      4097

发现这种语法创建出来的索引Oracle也认为是自动创建的。
alter table wxh_tbd drop primary key;
@ind
NO ROWS

结果跟我们预料的一样,索引被级联的删除了。

5)创建表的同时,指定主键,但是语法上特殊了一点点。创建了一个非唯一索引
create table wxh_tbd(id number ,primary key (id) using index (create index ttt on wxh_tbd(id)));
select PROPERTY from ind$  where OBJ#='193619';

  PROPERTY
----------
      4096
由于是非唯一索引,因此值是4096      
@ind

TABLE_NAME                INDEX_NAME                     COLUMN_NAME          TABLESPACE_NAME INDEX_TYPE
------------------------- ------------------------------ -------------------- --------------- ----------------------
WXH_TBD                   TTT                             ID                   SYSTEM          NORMAL


但是结果却出乎我们的意料,索引没有级联删除。


这里可以得出一个结论:
1)对于Oracle自动(递归)创建出来的唯一索引,在进行约束(唯一约束、主键约束)删除的时候,Oracle会级联把索引也删除。特别需要注意
必须满足两个条件,1)索引必须是唯一 2)必须是Oracle自动创建。上面的例子5里,虽然Oracle也认为是自动创建的,但是由于不是唯一索引,因此也不会被Oracle级联删除。

2)对于我们手工创建的索引,在进行约束(唯一约束、主键约束)删除的时候,由于不是Oracle自动创建的,因此Oracle会保留索引。

后记:
1)拿10046跟踪drop primary key,会看到有递归的sql,去查询ind$表,并且查询了property列(红体字)。类似如下:
select i.obj#,i.ts#,i.file#,i.block#,i.intcols,i.type#,i.flags,i.property,
  i.pctfree$,i.initrans,i.maxtrans,i.blevel,i.leafcnt,i.distkey,i.lblkkey,
  i.dblkkey,i.clufac,i.cols,i.analyzetime,i.samplesize,i.dataobj#,
  nvl(i.degree,1),nvl(i.instances,1),i.rowcnt,mod(i.pctthres$,256),
  i.indmethod#,i.trunccnt,nvl(c.unicols,0),nvl(c.deferrable#+c.valid#,0),
  nvl(i.spare1,i.intcols),i.spare4,i.spare2,i.spare6,decode(i.pctthres$,null,
  null,mod(trunc(i.pctthres$/256),256)),ist.cachedblk,ist.cachehit,
  ist.logicalread
from
ind$ i, ind_stats$ ist, (select enabled, min(cols) unicols,
  min(to_number(bitand(defer,1))) deferrable#,min(to_number(bitand(defer,4)))
  valid# from cdef$ where obj#=:1 and enabled > 1 group by enabled) c where
  i.obj#=c.enabled(+) and i.obj# = ist.obj#(+) and i.bo#=:1 order by i.obj#

2)由于property值都是由2的倍数值的和组成的,那么一个简单的判定是不是满足递归删除索引的公式就是:
bitand(ind$.property,4097) = 4097






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

转载于:http://blog.itpub.net/22034023/viewspace-735231/

微软登录OAuth 2.0授权流程 OAuth 2.0是一个关于授权的开放网络标准,它允许第三方应用获取用户数据,是目前最流行的授权机制。微软身份平台支持OAuth 2.0授权码流程,使得客户端应用程序能够获得对受保护资源(如网络API)的授权访问。这一流程在保障用户数据安全的前提下,实现了应用的便捷登录与数据共享。当用户在一个支持OAuth 2.0的应用上,希望使用微软账号进行登录时,OAuth 2.0授权流程即被触发。 阅读详情

相关推荐

汇丰外包Java岗面试复盘:Zoom面1.5小时,从英语、粤语到现场敲代码的极限挑战

本文详细记录了汇丰银行外包Java岗位的面试全过程,包括多语言切换(英语、粤语)的技术沟通挑战和现场编码测试的实战经验。从高并发编程到JVM调优,面试不仅考察技术深度,更注重实战问题解决能力。文章分享了应对跨国银行技术面试的实用策略,帮助Java开发者在跨文化环境中提升竞争力。

weixin_42524824的博客 296

【第004篇】Oracle创建和删除约束索引示例

创建和删除约束索引

嘉&年华的博客 1159

2025小红书爬虫还能活?破解x-s签名+动态Cookie,亲测爬1000条笔记零封禁(附逆向全过程)

上周帮美妆行业的朋友爬小红书“口红推荐”笔记,刚发30个请求就被403,抓包一看x-s签名不对;换Cookie继续爬,爬50条又被封——小红书的反爬这两年简直是“地狱模式”:动态Cookie每10分钟过期,x-s签名算法季度更新,连请求头的User-Agent顺序错了都会被拦。。这篇文章不藏私,把逆向x-s签名的全过程、动态Cookie的维护技巧、1000条稳定爬取的实战代码全给你,连我踩过的8个坑都标出来了(最后附代理池配置,IP零封禁的关键)。

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 7156

Oracle删除主键保留索引的方法

yangtingkun的"如何判断索引是系统产生还是用户创建的"http://yangtingkun.itpub.net/post/468/160390中说到:对于主键唯一约束,如果没有事先建立索引的话,Oracle在创建的过...

672

oracle 删除主键索引_Oracle主键约束索引的一奇葩现象

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

weixin_42138788的博客 870

oracle新增、删除索引以及主键修改

--根据索引名,查询表索引字段 select * from user_ind_columns where index_name='索引名'; --根据表名,查询一张表的索引 select * from user_indexes where table_name='表名'; --根据索引名,查询属于哪张表 select * from all_indexes where index_name ='IN...

Smile yourlife 1万+

Oracle删除约束主键的语句

1.删除约束语句: alter table 表名 drop constraint 约束名; alter table mz_sf4 drop constraint pk_id1; 2.删除主键语句: alter table 表名 drop primary key; alter table mz_sf3 drop primary key; 如果出错:ORA-02273:此唯一主键

xue_yanan的博客 3万+

数据库表的主键唯一约束索引

1、MySQL 的 主键。   “主键”的完整称呼是“主键约束”。MySQL 主键约束是一个列或者列的组合(其中由多列组合的主键称为复合主键),其值能唯一地标识表中的每一行。这样的一列或多列称为表的主键,通过它可以强制表的实体完整性。。 (1)一个表可以没有主键,而且最多只能有一个主键。 (2)主键值必须唯一标识表中的每一行,且不能为 NULL,即同一个表中不可能存在两行数据有相同的主键值。 2、MySQL 的 唯一约束。   MySQL唯一约束(Unique Key)是指所有记录中字

C201008的专栏 1万+

SQL Server 2012 唯一约束(定义唯一约束删除唯一约束

文章目录准备知识定义唯一约束使用SSMS工具定义唯一约束使用SQL方式定义唯一约束方式一:在创建数据表的时候定义唯一约束方式二:修改数据表定义唯一约束删除唯一约束使用SSMS工具删除唯一约束方式一:在对象资源管理器中删除唯一约束方式二:在表设计器中删除唯一约束使用SQL方式删除唯一约束 准备知识     如果要求数据表中的某列不能输入重复值,有两种约束可以做到。一种是主键约束,即该列是数据表...

柚子君的小窝 4万+

SQLServe联合主键、联合索引、唯一索引,聚集索引,和非聚集索引主键唯一约束和外键约束索引运算总结

介绍了以下的索引主键约束的创建、使用和注意事项:SQLServe联合主键、联合索引、唯一索引,聚集索引,和非聚集索引主键唯一约束和外键约束索引运算总结;索引/键 表设计器 数据空间规范和ON [PRIMARY]介绍

munangs的博客 8549

主键约束唯一约束

主键约束唯一约束主键约束唯一约束的区别普通索引和唯一索引Mysql中的索引普通索引(非唯一索引)唯一索引唯一索引主键约束的唯一索引唯一约束的唯一索引创建唯一索引删除主键约束唯一约束自动创建的唯一索引 主键约束唯一约束都会创建唯一索引 主键约束唯一约束的区别 不同之处在于主键约束索引键(唯一索引)在定义上不允许为NULL,而唯一约束索引键(唯一索引)在定义上允许为NULL; ...

逐梦 6297

Oracle 10g删除主键约束后无法删除唯一约束索引问题的模拟与分析

原帖地址: http://hi.baidu.com/oracle88/blog/item/14e66913d1299c1cb9127b9d.html/cmtid/c041b9979d3e40077bf480fb   oracle 10g删除唯一约束时,需要手动删除唯一约束

gaohaiyang的专栏 7044

MYSQL中唯一约束和唯一索引的区别

1、唯一约束和唯一索引,都可以实现列数据的唯一,列值可以有null。 2、创建唯一约束,会自动创建一个同名的唯一索引,该索引不能单独删除删除约束自动删除索引唯一约束是通过唯一索引来实现数据的唯一。 3、创建一个唯一索引,这个索引就是独立,可以单独删除。 4、如果一个列上想有约束索引,且两者可以单独的删除。可以先建唯一索引,再建同名的唯一约束。 5、如果表的一个字段,要作为另外一个表的外键,...

Explorer2017的博客 3963

【MySQL知识点】唯一约束主键约束

本期学习唯一约束主键约束噢~唯一约束用于保证数据表中字段的唯一性,即表中字段的值不能重复出现。唯一约束是通过unique定义的。语法如下:#列级约束字段名 数据类型 unique;#表级约束unique(字段名1,字段名2…);列级约束定义在一个列上,只对该列起约束作用。表级约束是独立于列的定义,可以应用在一个表的多个列上。在MySQL中,为了快速查找表中的某条信息,可以通过设置主键实现。主键可以唯一标识表中的记录。主键约束通过定义,它相当于唯一约束和非空约束的组合,要求被约束字段。

颜颜yan_的博客 3481

数据库中相同列上创建主键索引简记

数据库中相同列上创建主键索引简记

CARE_G的博客 716

Oracle如何删除主键约束的同时也删除索引

一、现象 在oracle10g中删除主键约束后,在插入重复数据时候仍然报“ORA-00001”错误。 二、原因 Oracle在的10g版本中对内部函数"atbdui"进行了调整,导致在删除约束的时候无法删除用户创建的索引。这个现象被Oracle分类到了“PROBLEM”。 三、方法 在删除约束的时候需要显示的指定“drop index”选项来完成索引的级链删除。 例:a...

djun0426的博客 798

oracle删除主键后要注意也要删除对应的index,否则还会影响主外关系并出错

<br />RT

weiryang2009的专栏 791

oracle 删除主键约束_Oracle中常见约束索引的创建和使用

Oracle中常见约束(Constraints)的创建和分类:创建创建方式可分为两种:(一)可以在创建表的时候规定约束(通过 CREATE TABLE 语句)(二)或者在表创建之后也可以(通过 ALTER TABLE 语句)分类1、非空约束:not null作用:约束强制列不接受 NULL 值例:create 2、唯一约束:unique作用:约束唯一标识数据库表中的每条记录例:create tab...

weixin_39521651的博客 293

删除主键索引 oracle,删除主键无法删除对应索引问题 drop constraint

--在删除一个表主键的时候索引没有删掉的问题,如果主键索引是和主键约束一起建的,则删除约束的时候索引自动删除掉,如果是先建了索引,然后建立主键,则删除约束的时候索引不会一起被删除掉测试:--创建测试表create table dbmgr.test_pk as select * from REINSDATA.REINS_PROP_PLAN_ADJ where rownum <1000--创建...

weixin_35744849的博客 1601

删除主键约束时是否删除索引

删除主键时是否会删除索引? 答案取决于索引是创建主键自动创建的,还是创建主键前手工创建的。 测试如下: --建表 create table hqy_test(id integer) ;   --建索引 create (unique) index idx_hqy_id on hqy_test(id) ;   --加主键 alter table hqy_test add const

heqiyu34的专栏 1913

oracle 11g删除主键约束级联删除唯一索引

实际开发中,在创建表主键约束的时候,通常会级联创建唯一索引。 假设现在需要在联合主键中增加一个字段SO_COMPANY_CDE,刚开始的做法是删除主键约束,再重新创建联合主键 alter table CBS_AG_CNTR_MTHD drop CONSTRAINT PK_CBS_AG_CNTR_MTHD cascade; --确认约束索引删除情况   可以发现主键删除了,但是唯一索引依旧存在,因此如果插入重复的数据,还是会报违反约束的错误 处理方法:   在删除约束的时候需要显示的

lichao920926的博客 1783

快思聪编程之deal_for_windows

安装simpl_windows_2.08.41前需称安装simpl_plus_cross_compiler和crestron_database,最后安装vt_pro-e 工具

STM32单片机麦克纳姆轮小车以及操纵杆控制程序代码.zip

STM32单片机麦克纳姆轮小车以及操纵杆控制,这个是在我大二电子设计竞赛的准备工作中完成了最基本的驱动功能:能蓝牙手机控制上下左右及斜向总共8个方向的平移,还有原地正反转功能。当时想着使用操纵杆来遥控控制呢,只是学习比赛繁忙,就忘了去实现了。最后是工作后才完成的。毕业工作后整理东西才发现当时有这个想法,而且也觉得很有趣,并且在想应该不止8个方向的平移,理论能任意方向移动,于是就尝试写代码实现,理论先实现任意平移,再结合操纵杆控制实现任意平移,结合自带按键可旋转(其实操作杆是先实现的,控制其8方向平移,再开发任意方向平移)。先实现遥控器部分:操纵杆是有x、y运动轴组成可360°随意转动的,因为两个轴对应有滑动变阻器,所以单片机采用2个adc来读取对应的值,结合滑动范围0-4096(12bit)可以判断此时操纵杆的姿态,与2048对比得出其位于哪个象限。在操纵杆这边就直接读取adc,然后根据串口的自定义命令格式进行传输就可以了。我这里就用 #x轴adc值,y轴adc值* 来通知小车的平移姿态,但还要有自旋转,还好这个操纵杆也带了一个按键,藏在操作杆下面,于是可以用来切换控制旋转。这

上一篇: PL/SQL 事务持久化异常 / PL/SQL commit优化
下一篇: Oracle 什么时候select会产生redo?
cotchte0421
博客等级 码龄11年 5粉丝 110原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值